Grease Pencil v2 Branch
Improve current Grease Pencil in order to get a better 2D animation tool. More info in WIKI pages: https://wiki.blender.org/index.php/User:Antoniov Reviewed By: Severin, aligorith, campbellbarton Patch by @antoniov, with edits by @Severin. Differential Revision: https://developer.blender.org/D2115
This commit is contained in:
@@ -30957,6 +30957,93 @@
|
||||
y1="-16"
|
||||
x2="-93.75"
|
||||
y2="-16.264704" />
|
||||
<filter
|
||||
inkscape:label="Opacity"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter17385">
|
||||
<feColorMatrix
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 5 -1 "
|
||||
result="colormatrix"
|
||||
id="feColorMatrix17387" />
|
||||
<feComposite
|
||||
k4="0"
|
||||
k3="0"
|
||||
k1="0"
|
||||
in2="colormatrix"
|
||||
operator="arithmetic"
|
||||
k2="0.24"
|
||||
result="composite"
|
||||
id="feComposite17389" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient18134"
|
||||
id="radialGradient37501-3-6-2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
|
||||
cx="135.83771"
|
||||
cy="117.97826"
|
||||
fx="135.83771"
|
||||
fy="117.97826"
|
||||
r="8" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient18134"
|
||||
id="radialGradient37501-3-6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-0.08933014,-0.7764284,0.7350832,-0.08334857,57.410559,233.30156)"
|
||||
cx="135.83771"
|
||||
cy="117.97826"
|
||||
fx="135.83771"
|
||||
fy="117.97826"
|
||||
r="8" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient18134"
|
||||
id="linearGradient17463"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="121.19734"
|
||||
y1="105.94044"
|
||||
x2="148.06364"
|
||||
y2="137.6748" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient16595"
|
||||
id="linearGradient17281"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(144,188)"
|
||||
x1="209"
|
||||
y1="238"
|
||||
x2="226.625"
|
||||
y2="251.71078" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient18134"
|
||||
id="linearGradient31399"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="62.793919"
|
||||
y1="133.73566"
|
||||
x2="64.109718"
|
||||
y2="135.18265" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient319"
|
||||
id="linearGradient31452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="121.19734"
|
||||
y1="105.94044"
|
||||
x2="148.06364"
|
||||
y2="137.6748" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1610-36-6-5"
|
||||
id="linearGradient31454"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(144,188)"
|
||||
x1="209"
|
||||
y1="238"
|
||||
x2="226.625"
|
||||
y2="251.71078" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@@ -30968,16 +31055,16 @@
|
||||
objecttolerance="10000"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="40.768576"
|
||||
inkscape:cx="236.56738"
|
||||
inkscape:cy="163.14077"
|
||||
inkscape:zoom="10.192144"
|
||||
inkscape:cx="406.73801"
|
||||
inkscape:cy="204.25086"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g24024-1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="982"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="28"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="987"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="true"
|
||||
showguides="true"
|
||||
@@ -91590,8 +91677,7 @@
|
||||
cx="304.0946"
|
||||
cy="242.89087"
|
||||
rx="0.59120387"
|
||||
ry="0.61330098"
|
||||
d="m 304.68581,242.89087 c 0,0.33872 -0.26469,0.6133 -0.59121,0.6133 -0.32651,0 -0.5912,-0.27458 -0.5912,-0.6133 0,-0.33872 0.26469,-0.6133 0.5912,-0.6133 0.32652,0 0.59121,0.27458 0.59121,0.6133 z" />
|
||||
ry="0.61330098" />
|
||||
<ellipse
|
||||
sodipodi:ry="0.61330098"
|
||||
sodipodi:rx="0.59120387"
|
||||
@@ -91602,8 +91688,7 @@
|
||||
cx="315.98523"
|
||||
cy="242.95337"
|
||||
rx="0.59120387"
|
||||
ry="0.61330098"
|
||||
d="m 316.57643,242.95337 c 0,0.33872 -0.26469,0.6133 -0.5912,0.6133 -0.32651,0 -0.5912,-0.27458 -0.5912,-0.6133 0,-0.33872 0.26469,-0.6133 0.5912,-0.6133 0.32651,0 0.5912,0.27458 0.5912,0.6133 z" />
|
||||
ry="0.61330098" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#clipPath15455-9)"
|
||||
@@ -91819,8 +91904,7 @@
|
||||
cy="242.89087"
|
||||
cx="304.0946"
|
||||
id="ellipse15366"
|
||||
style="opacity:0.51799999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 304.68581,242.89087 c 0,0.33872 -0.26469,0.6133 -0.59121,0.6133 -0.32651,0 -0.5912,-0.27458 -0.5912,-0.6133 0,-0.33872 0.26469,-0.6133 0.5912,-0.6133 0.32652,0 0.59121,0.27458 0.59121,0.6133 z" />
|
||||
style="opacity:0.51799999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<ellipse
|
||||
sodipodi:ry="0.61330098"
|
||||
sodipodi:rx="0.59120387"
|
||||
@@ -91831,8 +91915,7 @@
|
||||
cy="242.95337"
|
||||
cx="315.98523"
|
||||
id="ellipse15368"
|
||||
style="opacity:0.51799999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 316.57643,242.95337 c 0,0.33872 -0.26469,0.6133 -0.5912,0.6133 -0.32651,0 -0.5912,-0.27458 -0.5912,-0.6133 0,-0.33872 0.26469,-0.6133 0.5912,-0.6133 0.32651,0 0.5912,0.27458 0.5912,0.6133 z" />
|
||||
style="opacity:0.51799999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(189.00803,-79.37555)"
|
||||
@@ -91942,6 +92025,382 @@
|
||||
style="color:#000000;fill:url(#radialGradient14216);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline;enable-background:new"
|
||||
id="g17465"
|
||||
transform="translate(62.844714,-106.93345)">
|
||||
<g
|
||||
transform="matrix(0.7,0,0,0.7,146.7,264.8)"
|
||||
id="ICON_COLOR-1-9"
|
||||
style="display:inline;enable-background:new">
|
||||
<rect
|
||||
y="238"
|
||||
x="341"
|
||||
height="16"
|
||||
width="16"
|
||||
id="rect36341-2-0"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
id="g36343-7-5"
|
||||
transform="translate(0,-12)">
|
||||
<g
|
||||
transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)"
|
||||
id="g36345-0-4">
|
||||
<path
|
||||
transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36349-4-2"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="-2.8145849"
|
||||
inkscape:transform-center-y="-3.2499984" />
|
||||
<path
|
||||
inkscape:transform-center-y="1.6729808e-005"
|
||||
inkscape:transform-center-x="-3.2630798"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36351-3-6"
|
||||
style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)" />
|
||||
<path
|
||||
transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36353-9-8"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="-2.8145756"
|
||||
inkscape:transform-center-y="3.2500173" />
|
||||
<path
|
||||
inkscape:transform-center-y="3.249994"
|
||||
inkscape:transform-center-x="2.8145978"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36355-6-4"
|
||||
style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)" />
|
||||
<path
|
||||
transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36357-5-2"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="3.2630773" />
|
||||
<path
|
||||
inkscape:transform-center-x="2.8145777"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36359-0-5"
|
||||
style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
|
||||
inkscape:transform-center-y="-3.2500006" />
|
||||
</g>
|
||||
<circle
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
id="path36361-8-8"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
<circle
|
||||
style="display:inline;opacity:0.3;fill:url(#radialGradient37501-3-6);fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36363-2-9"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
<circle
|
||||
transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)"
|
||||
style="fill:none;stroke:url(#linearGradient17463);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path36365-2-9"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:transform-center-y="0.19622957"
|
||||
inkscape:transform-center-x="-1.373607"
|
||||
id="ICON_RESTRICT_SELECT_OFF-9"
|
||||
style="display:inline;enable-background:new"
|
||||
transform="matrix(0.45975513,-0.19653299,0.19653299,0.45975513,138.04837,311.70175)">
|
||||
<path
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient17281);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;enable-background:accumulate"
|
||||
d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
|
||||
id="path45378-1-5-6-6"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate"
|
||||
id="rect45374-0-5-6-1"
|
||||
width="16"
|
||||
height="16"
|
||||
x="362"
|
||||
y="430" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -2.25,2.25 z"
|
||||
id="path17835-7-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 368.34375,433.75 0,5.75"
|
||||
id="path17845-9-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
style="display:inline;filter:url(#filter17385);enable-background:new"
|
||||
id="g17465-0"
|
||||
transform="translate(41.727744,-106.93345)">
|
||||
<g
|
||||
transform="matrix(0.7,0,0,0.7,146.7,264.8)"
|
||||
id="ICON_COLOR-1-9-4"
|
||||
style="display:inline;enable-background:new">
|
||||
<rect
|
||||
y="238"
|
||||
x="341"
|
||||
height="16"
|
||||
width="16"
|
||||
id="rect36341-2-0-1"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
id="g36343-7-5-5"
|
||||
transform="translate(0,-12)">
|
||||
<g
|
||||
transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)"
|
||||
id="g36345-0-4-4">
|
||||
<path
|
||||
transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ff6600;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36349-4-2-6"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="-2.8145849"
|
||||
inkscape:transform-center-y="-3.2499984" />
|
||||
<path
|
||||
inkscape:transform-center-y="1.6729808e-005"
|
||||
inkscape:transform-center-x="-3.2630798"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36351-3-6-5"
|
||||
style="fill:#ad2f94;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(0.3484724,0.6035735,-0.603572,0.3484734,154.13836,102.27942)" />
|
||||
<path
|
||||
transform="matrix(-0.3484724,0.6035735,-0.603572,-0.3484733,246.13507,184.51913)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#0060f0;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36353-9-8-2"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="-2.8145756"
|
||||
inkscape:transform-center-y="3.2500173" />
|
||||
<path
|
||||
inkscape:transform-center-y="3.249994"
|
||||
inkscape:transform-center-x="2.8145978"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36355-6-4-4"
|
||||
style="fill:#00d4aa;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(-0.6969448,2.2484149e-8,-4.6257528e-8,-0.6969467,220.91956,305.31067)" />
|
||||
<path
|
||||
transform="matrix(-0.3484724,-0.6035734,0.603572,-0.3484734,103.69972,343.86251)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ccff00;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36357-5-2-5"
|
||||
sodipodi:cx="132"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:ry="8"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
sodipodi:start="4.712389"
|
||||
sodipodi:end="5.7595865"
|
||||
inkscape:transform-center-x="3.2630773" />
|
||||
<path
|
||||
inkscape:transform-center-x="2.8145777"
|
||||
sodipodi:end="5.7595865"
|
||||
sodipodi:start="4.712389"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 Z"
|
||||
sodipodi:ry="8"
|
||||
sodipodi:rx="8"
|
||||
sodipodi:cy="118"
|
||||
sodipodi:cx="132"
|
||||
id="path36359-0-5-9"
|
||||
style="fill:#ffbf0e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
sodipodi:type="arc"
|
||||
transform="matrix(0.3484724,-0.6035734,0.603572,0.3484733,11.703006,261.6228)"
|
||||
inkscape:transform-center-y="-3.2500006" />
|
||||
</g>
|
||||
<circle
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
id="path36361-8-8-0"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.98948926;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
transform="matrix(0.8124999,0,0,0.8045157,241.75,163.13011)"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
<circle
|
||||
style="display:inline;opacity:0.3;fill:url(#radialGradient37501-3-6-2);fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path36363-2-9-7"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
transform="matrix(-0.7451143,-0.08386971,0.08492794,-0.7396793,437.33358,356.39712)"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
<circle
|
||||
transform="matrix(0.6860851,0,0,0.6874876,258.44808,176.87656)"
|
||||
style="fill:none;stroke:url(#linearGradient31452);stroke-width:1.45605874;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path36365-2-9-7"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
cx="132"
|
||||
cy="118"
|
||||
r="8" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:transform-center-y="0.19622957"
|
||||
inkscape:transform-center-x="-1.373607"
|
||||
id="ICON_RESTRICT_SELECT_OFF-9-8"
|
||||
style="display:inline;enable-background:new"
|
||||
transform="matrix(0.45975513,-0.19653299,0.19653299,0.45975513,138.04837,311.70175)">
|
||||
<path
|
||||
style="display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient31454);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;enable-background:accumulate"
|
||||
d="m 367.75,440.75 1.75,-1.5 2.5,5.25 1.75,-1 -2.25,-5 2.5,0 -6.25,-6.25 z"
|
||||
id="path45378-1-5-6-6-9"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate"
|
||||
id="rect45374-0-5-6-1-0"
|
||||
width="16"
|
||||
height="16"
|
||||
x="362"
|
||||
y="430" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 367.5,431.5 7,7.25 -3,0 2.5,4.75 -1.75,1 -2.5,-5 -2.25,2.25 z"
|
||||
id="path17835-7-5-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 368.34375,433.75 0,5.75"
|
||||
id="path17845-9-6-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
|
||||
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
BIN
release/datafiles/blender_icons16/icon16_restrict_color_off.dat
Normal file
BIN
release/datafiles/blender_icons16/icon16_restrict_color_off.dat
Normal file
Binary file not shown.
BIN
release/datafiles/blender_icons16/icon16_restrict_color_on.dat
Normal file
BIN
release/datafiles/blender_icons16/icon16_restrict_color_on.dat
Normal file
Binary file not shown.
BIN
release/datafiles/blender_icons32/icon32_restrict_color_off.dat
Normal file
BIN
release/datafiles/blender_icons32/icon32_restrict_color_off.dat
Normal file
Binary file not shown.
BIN
release/datafiles/blender_icons32/icon32_restrict_color_on.dat
Normal file
BIN
release/datafiles/blender_icons32/icon32_restrict_color_on.dat
Normal file
Binary file not shown.
@@ -136,7 +136,7 @@ class GreasePencilStrokeEditPanel:
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
is_3d_view = context.space_data.type == 'VIEW_3D'
|
||||
is_3d_view = context.space_data.type == 'VIEW_3D'
|
||||
|
||||
if not is_3d_view:
|
||||
layout.label(text="Select:")
|
||||
@@ -151,18 +151,19 @@ class GreasePencilStrokeEditPanel:
|
||||
col.operator("gpencil.select_linked")
|
||||
col.operator("gpencil.select_more")
|
||||
col.operator("gpencil.select_less")
|
||||
|
||||
layout.separator()
|
||||
col.operator("gpencil.palettecolor_select")
|
||||
|
||||
layout.label(text="Edit:")
|
||||
row = layout.row(align=True)
|
||||
row.operator("gpencil.copy", text="Copy")
|
||||
row.operator("gpencil.paste", text="Paste")
|
||||
row.operator("gpencil.paste", text="Paste").type = 'COPY'
|
||||
row.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.operator("gpencil.delete", text="Delete")
|
||||
col.operator("gpencil.delete")
|
||||
col.operator("gpencil.duplicate_move", text="Duplicate")
|
||||
col.operator("transform.mirror", text="Mirror")
|
||||
if is_3d_view:
|
||||
col.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -176,9 +177,92 @@ class GreasePencilStrokeEditPanel:
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.operator("transform.bend", text="Bend")
|
||||
col.operator("transform.mirror", text="Mirror")
|
||||
col.operator("transform.shear", text="Shear")
|
||||
col.operator("transform.tosphere", text="To Sphere")
|
||||
|
||||
layout.separator()
|
||||
col = layout.column(align=True)
|
||||
col.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction")
|
||||
col.operator("gpencil.stroke_change_color", text="Move to Color")
|
||||
|
||||
layout.separator()
|
||||
col = layout.column(align=True)
|
||||
col.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
|
||||
col.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
|
||||
col.operator("gpencil.stroke_flip", text="Flip direction")
|
||||
|
||||
gpd = context.gpencil_data
|
||||
if gpd:
|
||||
col.prop(gpd, "show_stroke_direction", text="Show drawing direction")
|
||||
|
||||
|
||||
class GreasePencilBrushPanel:
|
||||
# subclass must set
|
||||
# bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_label = "Drawing Brushes"
|
||||
bl_category = "Grease Pencil"
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
@staticmethod
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
ts = context.scene.tool_settings
|
||||
if len(ts.gpencil_brushes) >= 2:
|
||||
brows = 3
|
||||
else:
|
||||
brows = 2
|
||||
col.template_list("GPENCIL_UL_brush", "", ts, "gpencil_brushes", ts.gpencil_brushes, "active_index", rows=brows)
|
||||
|
||||
col = row.column()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.brush_add", icon='ZOOMIN', text="")
|
||||
sub.operator("gpencil.brush_remove", icon='ZOOMOUT', text="")
|
||||
sub.menu("GPENCIL_MT_brush_specials", icon='DOWNARROW_HLT', text="")
|
||||
brush = context.active_gpencil_brush
|
||||
if brush:
|
||||
if len(ts.gpencil_brushes) > 1:
|
||||
col.separator()
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.brush_move", icon='TRIA_UP', text="").type = 'UP'
|
||||
sub.operator("gpencil.brush_move", icon='TRIA_DOWN', text="").type = 'DOWN'
|
||||
|
||||
# Brush details
|
||||
if brush is not None:
|
||||
row = layout.row()
|
||||
row.prop(brush, "line_width")
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "use_random_pressure", text='', icon='RNDCURVE')
|
||||
row.prop(brush, "pen_sensitivity_factor", slider=True)
|
||||
row.prop(brush, "use_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "use_random_strength", text='', icon='RNDCURVE')
|
||||
row.prop(brush, "strength", slider=True)
|
||||
row.prop(brush, "use_strength_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "random_press", slider=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_jitter_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = layout.row()
|
||||
row.prop(brush, "angle", slider=True)
|
||||
row.prop(brush, "angle_factor", text="Factor", slider=True)
|
||||
|
||||
box = layout.box()
|
||||
col = box.column(align=True)
|
||||
col.label(text="Stroke Quality:")
|
||||
col.prop(brush, "pen_smooth_factor")
|
||||
col.prop(brush, "pen_smooth_steps")
|
||||
col.separator()
|
||||
row = col.row(align=False)
|
||||
row.prop(brush, "pen_subdivision_steps")
|
||||
row.prop(brush, "random_subdiv", text='Randomness', slider=True)
|
||||
|
||||
|
||||
class GreasePencilStrokeSculptPanel:
|
||||
# subclass must set
|
||||
@@ -203,7 +287,7 @@ class GreasePencilStrokeSculptPanel:
|
||||
tool = settings.tool
|
||||
brush = settings.brush
|
||||
|
||||
layout.column().prop(settings, "tool", expand=True)
|
||||
layout.column().prop(settings, "tool")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(brush, "size", slider=True)
|
||||
@@ -211,6 +295,11 @@ class GreasePencilStrokeSculptPanel:
|
||||
row.prop(brush, "strength", slider=True)
|
||||
row.prop(brush, "use_pressure_strength", text="")
|
||||
col.prop(brush, "use_falloff")
|
||||
if tool in {'SMOOTH', 'RANDOMIZE'}:
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
|
||||
row.prop(settings, "affect_strength", text="Strength", icon='COLOR', toggle=True)
|
||||
row.prop(settings, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -220,18 +309,54 @@ class GreasePencilStrokeSculptPanel:
|
||||
row = layout.row(align=True)
|
||||
row.prop_enum(brush, "direction", 'ADD', text="Pinch")
|
||||
row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate")
|
||||
elif tool == 'TWIST':
|
||||
elif settings.tool == 'TWIST':
|
||||
row = layout.row(align=True)
|
||||
row.prop_enum(brush, "direction", 'SUBTRACT', text="CW")
|
||||
row.prop_enum(brush, "direction", 'ADD', text="CCW")
|
||||
|
||||
layout.separator()
|
||||
layout.prop(settings, "use_select_mask")
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "use_select_mask")
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "selection_alpha", slider=True)
|
||||
|
||||
if tool == 'SMOOTH':
|
||||
layout.prop(brush, "affect_pressure")
|
||||
|
||||
|
||||
class GreasePencilBrushCurvesPanel:
|
||||
# subclass must set
|
||||
# bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_label = "Grease Pencil Curves"
|
||||
bl_category = "Grease Pencil"
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if context.active_gpencil_brush is None:
|
||||
return False
|
||||
|
||||
brush = context.active_gpencil_brush
|
||||
return bool(brush)
|
||||
|
||||
@staticmethod
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
brush = context.active_gpencil_brush
|
||||
# Brush
|
||||
layout.label("Sensitivity")
|
||||
box = layout.box()
|
||||
box.template_curve_mapping(brush, "curve_sensitivity", brush=True)
|
||||
|
||||
layout.label("Strength")
|
||||
box = layout.box()
|
||||
box.template_curve_mapping(brush, "curve_strength", brush=True)
|
||||
|
||||
layout.label("Jitter")
|
||||
box = layout.box()
|
||||
box.template_curve_mapping(brush, "curve_jitter", brush=True)
|
||||
|
||||
|
||||
###############################
|
||||
|
||||
class GPENCIL_PIE_tool_palette(Menu):
|
||||
@@ -282,6 +407,7 @@ class GPENCIL_PIE_tool_palette(Menu):
|
||||
col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT')
|
||||
col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1')
|
||||
col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED')
|
||||
col.operator("gpencil.palettecolor_select", text="Select Color", icon='COLOR')
|
||||
|
||||
# NE - Select (Modal)
|
||||
col = pie.column()
|
||||
@@ -315,24 +441,47 @@ class GPENCIL_PIE_settings_palette(Menu):
|
||||
pie = layout.menu_pie()
|
||||
# gpd = context.gpencil_data
|
||||
gpl = context.active_gpencil_layer
|
||||
palcolor = context.active_gpencil_palettecolor
|
||||
brush = context.active_gpencil_brush
|
||||
|
||||
# W - Stroke draw settings
|
||||
col = pie.column(align=True)
|
||||
col.label(text="Stroke")
|
||||
col.prop(gpl, "color", text="")
|
||||
col.prop(gpl, "alpha", text="", slider=True)
|
||||
if palcolor is not None:
|
||||
col.label(text="Stroke")
|
||||
col.prop(palcolor, "color", text="")
|
||||
col.prop(palcolor, "alpha", text="", slider=True)
|
||||
|
||||
# E - Fill draw settings
|
||||
col = pie.column(align=True)
|
||||
col.label(text="Fill")
|
||||
col.prop(gpl, "fill_color", text="")
|
||||
col.prop(gpl, "fill_alpha", text="", slider=True)
|
||||
if palcolor is not None:
|
||||
col.label(text="Fill")
|
||||
col.prop(palcolor, "fill_color", text="")
|
||||
col.prop(palcolor, "fill_alpha", text="", slider=True)
|
||||
|
||||
# S - Layer settings
|
||||
# S Brush settings
|
||||
col = pie.column()
|
||||
col.prop(gpl, "line_width", slider=True)
|
||||
# col.prop(gpl, "use_volumetric_strokes")
|
||||
col.prop(gpl, "use_onion_skinning")
|
||||
col.label("Active Brush: ")
|
||||
|
||||
row = col.row()
|
||||
row.operator_context = 'EXEC_REGION_WIN'
|
||||
row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA')
|
||||
row.prop(brush, "name", text="")
|
||||
|
||||
col.prop(brush, "line_width", slider=True)
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "use_random_pressure", text='', icon='RNDCURVE')
|
||||
row.prop(brush, "pen_sensitivity_factor", slider=True)
|
||||
row.prop(brush, "use_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "use_random_strength", text='', icon='RNDCURVE')
|
||||
row.prop(brush, "strength", slider=True)
|
||||
row.prop(brush, "use_strength_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_jitter_pressure", text='', icon='STYLUS_PRESSURE')
|
||||
row = col.row()
|
||||
row.prop(brush, "angle", slider=True)
|
||||
row.prop(brush, "angle_factor", text="Factor", slider=True)
|
||||
|
||||
# N - Active Layer
|
||||
col = pie.column()
|
||||
@@ -347,6 +496,35 @@ class GPENCIL_PIE_settings_palette(Menu):
|
||||
row = col.row()
|
||||
row.prop(gpl, "lock")
|
||||
row.prop(gpl, "hide")
|
||||
col.prop(gpl, "use_onion_skinning")
|
||||
|
||||
# NW - Move stroke Down
|
||||
col = pie.column(align=True)
|
||||
col.label("Arrange Strokes")
|
||||
col.operator("gpencil.stroke_arrange", text="Send to Back").direction = 'BOTTOM'
|
||||
col.operator("gpencil.stroke_arrange", text="Send Backward").direction = 'DOWN'
|
||||
|
||||
# NE - Move stroke Up
|
||||
col = pie.column(align=True)
|
||||
col.label("Arrange Strokes")
|
||||
col.operator("gpencil.stroke_arrange", text="Bring to Front").direction = 'TOP'
|
||||
col.operator("gpencil.stroke_arrange", text="Bring Forward").direction = 'UP'
|
||||
|
||||
# SW - Move stroke to color
|
||||
col = pie.column(align=True)
|
||||
col.operator("gpencil.stroke_change_color", text="Move to Color")
|
||||
|
||||
# SE - Join strokes
|
||||
col = pie.column(align=True)
|
||||
col.label("Join Strokes")
|
||||
row = col.row()
|
||||
row.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
|
||||
row.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
|
||||
col.operator("gpencil.stroke_flip", text="Flip direction")
|
||||
|
||||
gpd = context.gpencil_data
|
||||
if gpd:
|
||||
col.prop(gpd, "show_stroke_direction", text="Show drawing direction")
|
||||
|
||||
|
||||
class GPENCIL_PIE_tools_more(Menu):
|
||||
@@ -411,6 +589,11 @@ class GPENCIL_PIE_sculpt(Menu):
|
||||
row.prop(brush, "strength", slider=True)
|
||||
# row.prop(brush, "use_pressure_strength", text="", icon_only=True)
|
||||
col.prop(brush, "use_falloff")
|
||||
if settings.tool in {'SMOOTH', 'RANDOMIZE'}:
|
||||
row = col.row(align=True)
|
||||
row.prop(settings, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
|
||||
row.prop(settings, "affect_strength", text="Strength", icon='COLOR', toggle=True)
|
||||
row.prop(settings, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
|
||||
|
||||
# S - Change Brush Type Shortcuts
|
||||
row = pie.row()
|
||||
@@ -422,6 +605,7 @@ class GPENCIL_PIE_sculpt(Menu):
|
||||
row = pie.row()
|
||||
row.prop_enum(settings, "tool", value='SMOOTH')
|
||||
row.prop_enum(settings, "tool", value='THICKNESS')
|
||||
row.prop_enum(settings, "tool", value='STRENGTH')
|
||||
row.prop_enum(settings, "tool", value='RANDOMIZE')
|
||||
|
||||
|
||||
@@ -448,6 +632,48 @@ class GPENCIL_MT_snap(Menu):
|
||||
###############################
|
||||
|
||||
|
||||
class GPENCIL_UL_brush(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.GPencilBrush)
|
||||
brush = item
|
||||
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
row = layout.row(align=True)
|
||||
row.prop(brush, "name", text="", emboss=False, icon='BRUSH_DATA')
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text="", icon_value=icon)
|
||||
|
||||
|
||||
class GPENCIL_UL_palettecolor(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.PaletteColor)
|
||||
palcolor = item
|
||||
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
if palcolor.lock:
|
||||
layout.active = False
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row(align=True)
|
||||
row.prop(palcolor, "color", text="", emboss=palcolor.is_stroke_visible)
|
||||
row.prop(palcolor, "fill_color", text="", emboss=palcolor.is_fill_visible)
|
||||
split.prop(palcolor, "info", text="", emboss=False)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(palcolor, "lock", text="", emboss=False)
|
||||
row.prop(palcolor, "hide", text="", emboss=False)
|
||||
if palcolor.ghost is True:
|
||||
icon = 'GHOST_DISABLED'
|
||||
else:
|
||||
icon = 'GHOST_ENABLED'
|
||||
row.prop(palcolor, "ghost", text="", icon=icon, emboss=False)
|
||||
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text="", icon_value=icon)
|
||||
|
||||
|
||||
class GPENCIL_UL_layer(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.GPencilLayer)
|
||||
@@ -457,15 +683,19 @@ class GPENCIL_UL_layer(UIList):
|
||||
if gpl.lock:
|
||||
layout.active = False
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
row = split.row(align=True)
|
||||
row.prop(gpl, "color", text="", emboss=gpl.is_stroke_visible)
|
||||
row.prop(gpl, "fill_color", text="", emboss=gpl.is_fill_visible)
|
||||
split.prop(gpl, "info", text="", emboss=False)
|
||||
row = layout.row(align=True)
|
||||
if gpl.is_parented:
|
||||
icon = 'BONE_DATA'
|
||||
else:
|
||||
icon = 'BLANK1'
|
||||
|
||||
row.label(text="", icon=icon)
|
||||
row.prop(gpl, "info", text="", emboss=False)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "lock", text="", emboss=False)
|
||||
row.prop(gpl, "hide", text="", emboss=False)
|
||||
row.prop(gpl, "unlock_color", text="", emboss=False)
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text="", icon_value=icon)
|
||||
@@ -489,11 +719,40 @@ class GPENCIL_MT_layer_specials(Menu):
|
||||
layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
|
||||
layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down")
|
||||
|
||||
|
||||
class GPENCIL_MT_brush_specials(Menu):
|
||||
bl_label = "Layer"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.operator("gpencil.brush_copy", icon='PASTEDOWN', text="Copy current drawing brush")
|
||||
layout.operator("gpencil.brush_presets_create", icon='HELP', text="Create a set of predefined brushes")
|
||||
|
||||
|
||||
class GPENCIL_MT_palettecolor_specials(Menu):
|
||||
bl_label = "Layer"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("gpencil.palettecolor_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
|
||||
layout.operator("gpencil.palettecolor_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("gpencil.palettecolor_lock_all", icon='LOCKED', text="Lock All")
|
||||
layout.operator("gpencil.palettecolor_unlock_all", icon='UNLOCKED', text="UnLock All")
|
||||
layout.operator("gpencil.palettecolor_copy", icon='PASTEDOWN', text="Copy Color")
|
||||
|
||||
|
||||
class GreasePencilDataPanel:
|
||||
# subclass must set
|
||||
# bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_label = "Grease Pencil"
|
||||
bl_label = "Grease Pencil Layers"
|
||||
bl_region_type = 'UI'
|
||||
|
||||
@staticmethod
|
||||
@@ -553,46 +812,56 @@ class GreasePencilDataPanel:
|
||||
col.separator()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.layer_isolate", icon='SOLO_OFF', text="").affect_visibility = False
|
||||
sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
|
||||
sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
|
||||
|
||||
if gpl:
|
||||
self.draw_layer(layout, gpl)
|
||||
self.draw_layer(context, layout, gpl)
|
||||
|
||||
def draw_layer(self, layout, gpl):
|
||||
def draw_layer(self, context, layout, gpl):
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "opacity", text="Opacity", slider=True)
|
||||
# layer settings
|
||||
split = layout.split(percentage=0.5)
|
||||
split.active = not gpl.lock
|
||||
|
||||
# Column 1 - Stroke
|
||||
col = split.column(align=True)
|
||||
col.label(text="Stroke:")
|
||||
col.prop(gpl, "color", text="")
|
||||
col.prop(gpl, "alpha", slider=True)
|
||||
|
||||
# Column 2 - Fill
|
||||
col = split.column(align=True)
|
||||
col.label(text="Fill:")
|
||||
col.prop(gpl, "fill_color", text="")
|
||||
col.prop(gpl, "fill_alpha", text="Opacity", slider=True)
|
||||
|
||||
# Options
|
||||
col = layout.column(align=True)
|
||||
col.active = not gpl.lock
|
||||
col.prop(gpl, "line_width", slider=True)
|
||||
|
||||
split = layout.split(percentage=0.5)
|
||||
split.active = not gpl.lock
|
||||
|
||||
col = split.column(align=True)
|
||||
col.prop(gpl, "use_volumetric_strokes")
|
||||
col.prop(gpl, "show_points", text="Points")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.prop(gpl, "use_hq_fill")
|
||||
col.active = not gpl.lock
|
||||
col.prop(gpl, "show_x_ray")
|
||||
|
||||
layout.separator()
|
||||
col.label("Tint")
|
||||
col.prop(gpl, "tint_color", text="")
|
||||
col.prop(gpl, "tint_factor", text="Factor", slider=True)
|
||||
|
||||
col = split.column(align=True)
|
||||
col.active = not gpl.lock
|
||||
col.prop(gpl, "show_points", text="Points")
|
||||
# Full-Row - Parent
|
||||
'''
|
||||
row = layout.row()
|
||||
if context.area.type == 'VIEW_3D' and not gpl.lock:
|
||||
row.enabled = True
|
||||
else:
|
||||
row.enabled = False
|
||||
'''
|
||||
|
||||
# col = row.column()
|
||||
if context.space_data.type == 'VIEW_3D':
|
||||
col.label(text="Parent:")
|
||||
col.prop(gpl, "parent", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.prop(gpl, "parent_type", text="")
|
||||
parent = gpl.parent
|
||||
if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
|
||||
sub.prop_search(gpl, "parent_bone", parent.data, "bones", text="")
|
||||
|
||||
# Full-Row - Thickness
|
||||
row = layout.row(align=True)
|
||||
row.active = not gpl.lock
|
||||
row.prop(gpl, "line_change", text="Thickness change", slider=True)
|
||||
row.operator("gpencil.stroke_apply_thickness", icon='STYLUS_PRESSURE', text="")
|
||||
|
||||
# Full-Row - Frame Locking (and Delete Frame)
|
||||
row = layout.row(align=True)
|
||||
@@ -606,8 +875,6 @@ class GreasePencilDataPanel:
|
||||
row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
|
||||
row.operator("gpencil.active_frame_delete", text="", icon='X')
|
||||
|
||||
layout.separator()
|
||||
|
||||
# Onion skinning
|
||||
col = layout.column(align=True)
|
||||
col.active = not gpl.lock
|
||||
@@ -633,14 +900,103 @@ class GreasePencilDataPanel:
|
||||
row.prop(gpl, "after_color", text="")
|
||||
sub.prop(gpl, "ghost_after_range", text="After")
|
||||
|
||||
# Smooth and subdivide new strokes
|
||||
layout.separator()
|
||||
col = layout.column(align=True)
|
||||
col.label(text="New Stroke Quality:")
|
||||
col.prop(gpl, "pen_smooth_factor")
|
||||
col.prop(gpl, "pen_smooth_steps")
|
||||
col.separator()
|
||||
col.prop(gpl, "pen_subdivision_steps")
|
||||
|
||||
class GreasePencilPaletteColorPanel:
|
||||
# subclass must set
|
||||
bl_label = "Grease Pencil Colors"
|
||||
bl_region_type = 'UI'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if context.gpencil_data is None:
|
||||
return False
|
||||
|
||||
gpd = context.gpencil_data
|
||||
return bool(gpd.layers.active)
|
||||
|
||||
@staticmethod
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
palette = context.active_gpencil_palette
|
||||
|
||||
if palette:
|
||||
row = layout.row(align=True)
|
||||
row.operator_context = 'EXEC_REGION_WIN'
|
||||
row.operator_menu_enum("gpencil.palette_change", "palette", text="", icon='COLOR')
|
||||
row.prop(palette, "name", text="")
|
||||
row.operator("gpencil.palette_add", icon='ZOOMIN', text="")
|
||||
row.operator("gpencil.palette_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
# Palette colors
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
if len(palette.colors) >= 2:
|
||||
color_rows = 5
|
||||
else:
|
||||
color_rows = 2
|
||||
col.template_list("GPENCIL_UL_palettecolor", "", palette, "colors", palette.colors, "active_index",
|
||||
rows=color_rows)
|
||||
|
||||
col = row.column()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.palettecolor_add", icon='ZOOMIN', text="")
|
||||
sub.operator("gpencil.palettecolor_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
palcol = context.active_gpencil_palettecolor
|
||||
if palcol:
|
||||
sub.menu("GPENCIL_MT_palettecolor_specials", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
if len(palette.colors) > 1:
|
||||
col.separator()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.palettecolor_move", icon='TRIA_UP', text="").direction = 'UP'
|
||||
sub.operator("gpencil.palettecolor_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
|
||||
|
||||
col.separator()
|
||||
sub = col.column(align=True)
|
||||
sub.operator("gpencil.palettecolor_isolate", icon='LOCKED', text="").affect_visibility = False
|
||||
sub.operator("gpencil.palettecolor_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
|
||||
sub.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="")
|
||||
sub.operator("gpencil.palette_lock_layer", icon='COLOR', text="")
|
||||
|
||||
pcolor = palette.colors.active
|
||||
if pcolor:
|
||||
self.draw_palettecolors(layout, pcolor)
|
||||
|
||||
# ----------------------------------------------
|
||||
# Draw palette colors
|
||||
# ----------------------------------------------
|
||||
def draw_palettecolors(self, layout, pcolor):
|
||||
# color settings
|
||||
split = layout.split(percentage=0.5)
|
||||
split.active = not pcolor.lock
|
||||
|
||||
# Column 1 - Stroke
|
||||
col = split.column(align=True)
|
||||
col.active = not pcolor.lock
|
||||
col.label(text="Stroke:")
|
||||
col.prop(pcolor, "color", text="")
|
||||
col.prop(pcolor, "alpha", slider=True)
|
||||
|
||||
# Column 2 - Fill
|
||||
col = split.column(align=True)
|
||||
col.active = not pcolor.lock
|
||||
col.label(text="Fill:")
|
||||
col.prop(pcolor, "fill_color", text="")
|
||||
col.prop(pcolor, "fill_alpha", text="Opacity", slider=True)
|
||||
|
||||
# Options
|
||||
split = layout.split(percentage=0.5)
|
||||
split.active = not pcolor.lock
|
||||
|
||||
col = split.column(align=True)
|
||||
col.active = not pcolor.lock
|
||||
col.prop(pcolor, "use_volumetric_strokes")
|
||||
col = split.column(align=True)
|
||||
col.active = not pcolor.lock
|
||||
col.prop(pcolor, "use_hq_fill")
|
||||
|
||||
|
||||
class GreasePencilToolsPanel:
|
||||
|
||||
@@ -25,8 +25,10 @@ from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDrawingToolsPanel,
|
||||
GreasePencilStrokeEditPanel,
|
||||
GreasePencilStrokeSculptPanel,
|
||||
GreasePencilDataPanel
|
||||
)
|
||||
GreasePencilBrushPanel,
|
||||
GreasePencilBrushCurvesPanel,
|
||||
GreasePencilDataPanel,
|
||||
GreasePencilPaletteColorPanel)
|
||||
|
||||
|
||||
class CLIP_UL_tracking_objects(UIList):
|
||||
@@ -1126,6 +1128,16 @@ class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Pane
|
||||
# But, this should only be visible in "clip" view
|
||||
|
||||
|
||||
# Grease Pencil palette colors
|
||||
class CLIP_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, CLIP_PT_clip_view_panel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
# But, this should only be visible in "clip" view
|
||||
|
||||
|
||||
# Grease Pencil drawing tools
|
||||
class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
@@ -1141,6 +1153,15 @@ class CLIP_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
|
||||
|
||||
# Grease Pencil drawing brushes
|
||||
class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
|
||||
|
||||
# Grease Pencil drawing curves
|
||||
class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
|
||||
class CLIP_MT_view(Menu):
|
||||
bl_label = "View"
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@ from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDrawingToolsPanel,
|
||||
GreasePencilStrokeEditPanel,
|
||||
GreasePencilStrokeSculptPanel,
|
||||
GreasePencilBrushPanel,
|
||||
GreasePencilBrushCurvesPanel,
|
||||
GreasePencilDataPanel,
|
||||
GreasePencilPaletteColorPanel
|
||||
)
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
|
||||
@@ -1187,6 +1190,14 @@ class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel):
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
|
||||
|
||||
# Grease Pencil palette colors
|
||||
class IMAGE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
|
||||
|
||||
# Grease Pencil drawing tools
|
||||
class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
@@ -1202,5 +1213,15 @@ class IMAGE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
|
||||
|
||||
# Grease Pencil drawing brushes
|
||||
class IMAGE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
|
||||
|
||||
# Grease Pencil drawing curves
|
||||
class IMAGE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
||||
|
||||
@@ -25,8 +25,11 @@ from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDrawingToolsPanel,
|
||||
GreasePencilStrokeEditPanel,
|
||||
GreasePencilStrokeSculptPanel,
|
||||
GreasePencilBrushPanel,
|
||||
GreasePencilBrushCurvesPanel,
|
||||
GreasePencilDataPanel,
|
||||
GreasePencilToolsPanel,
|
||||
GreasePencilPaletteColorPanel,
|
||||
GreasePencilToolsPanel
|
||||
)
|
||||
|
||||
|
||||
@@ -464,6 +467,19 @@ class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel):
|
||||
return snode is not None and snode.node_tree is not None
|
||||
|
||||
|
||||
# Grease Pencil palette colors
|
||||
class NODE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
snode = context.space_data
|
||||
return snode is not None and snode.node_tree is not None
|
||||
|
||||
|
||||
class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
@@ -494,6 +510,16 @@ class NODE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
# Grease Pencil drawing brushes
|
||||
class NODE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
# Grease Pencil drawing curves
|
||||
class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
# -----------------------------
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from rna_prop_ui import PropertyPanel
|
||||
from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel, GreasePencilToolsPanel
|
||||
from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDataPanel,
|
||||
GreasePencilPaletteColorPanel,
|
||||
GreasePencilToolsPanel,
|
||||
)
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
|
||||
|
||||
@@ -1186,6 +1190,14 @@ class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Ou
|
||||
# But, it should only show up when there are images in the preview region
|
||||
|
||||
|
||||
class SEQUENCER_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, SequencerButtonsPanel_Output, Panel):
|
||||
bl_space_type = 'SEQUENCE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
# But, it should only show up when there are images in the preview region
|
||||
|
||||
|
||||
class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
|
||||
bl_space_type = 'SEQUENCE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel
|
||||
from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDataPanel,
|
||||
GreasePencilPaletteColorPanel,
|
||||
)
|
||||
from bl_ui.properties_paint_common import UnifiedPaintPanel
|
||||
from bpy.app.translations import contexts as i18n_contexts
|
||||
|
||||
@@ -139,7 +142,9 @@ class VIEW3D_HT_header(Header):
|
||||
# XXX: icon
|
||||
layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH')
|
||||
|
||||
layout.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
|
||||
row = layout.row(align=True)
|
||||
row.prop(context.tool_settings.gpencil_sculpt, "use_select_mask")
|
||||
row.prop(context.tool_settings.gpencil_sculpt, "selection_alpha", slider=True)
|
||||
|
||||
|
||||
class VIEW3D_MT_editor_menus(Menu):
|
||||
@@ -3079,6 +3084,13 @@ class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
|
||||
|
||||
class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
# NOTE: this is just a wrapper around the generic GP Panel
|
||||
|
||||
|
||||
class VIEW3D_PT_view3d_properties(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
|
||||
@@ -22,7 +22,9 @@ from bpy.types import Menu, Panel, UIList
|
||||
from bl_ui.properties_grease_pencil_common import (
|
||||
GreasePencilDrawingToolsPanel,
|
||||
GreasePencilStrokeEditPanel,
|
||||
GreasePencilStrokeSculptPanel
|
||||
GreasePencilStrokeSculptPanel,
|
||||
GreasePencilBrushPanel,
|
||||
GreasePencilBrushCurvesPanel
|
||||
)
|
||||
from bl_ui.properties_paint_common import (
|
||||
UnifiedPaintPanel,
|
||||
@@ -1965,6 +1967,15 @@ class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel)
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
||||
|
||||
# Grease Pencil drawing brushes
|
||||
class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
||||
# Grease Pencil drawingcurves
|
||||
class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
||||
|
||||
# Note: moved here so that it's always in last position in 'Tools' panels!
|
||||
class VIEW3D_PT_tools_history(View3DPanel, Panel):
|
||||
bl_category = "Tools"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* and keep comment above the defines.
|
||||
* Use STRINGIFY() rather than defining with quotes */
|
||||
#define BLENDER_VERSION 277
|
||||
#define BLENDER_SUBVERSION 1
|
||||
#define BLENDER_SUBVERSION 3
|
||||
/* Several breakages with 270, e.g. constraint deg vs rad */
|
||||
#define BLENDER_MINVERSION 270
|
||||
#define BLENDER_MINSUBVERSION 6
|
||||
|
||||
@@ -58,6 +58,9 @@ struct bPoseChannel;
|
||||
struct bGPdata;
|
||||
struct bGPDlayer;
|
||||
struct bGPDframe;
|
||||
struct bGPDpalette;
|
||||
struct bGPDpalettecolor;
|
||||
struct bGPDbrush;
|
||||
struct wmWindow;
|
||||
struct wmWindowManager;
|
||||
struct SpaceText;
|
||||
@@ -283,6 +286,9 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
|
||||
struct bGPdata *CTX_data_gpencil_data(const bContext *C);
|
||||
struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
|
||||
struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
|
||||
struct bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C);
|
||||
struct bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C);
|
||||
struct bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C);
|
||||
int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
|
||||
int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
|
||||
int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
|
||||
|
||||
@@ -31,19 +31,25 @@
|
||||
* \author Joshua Leung
|
||||
*/
|
||||
|
||||
struct ToolSettings;
|
||||
struct ListBase;
|
||||
struct bGPdata;
|
||||
struct bGPDlayer;
|
||||
struct bGPDframe;
|
||||
struct bGPDstroke;
|
||||
struct bGPDpalette;
|
||||
struct bGPDpalettecolor;
|
||||
struct Main;
|
||||
|
||||
/* ------------ Grease-Pencil API ------------------ */
|
||||
|
||||
void free_gpencil_stroke(struct bGPDstroke *gps);
|
||||
bool free_gpencil_strokes(struct bGPDframe *gpf);
|
||||
void free_gpencil_frames(struct bGPDlayer *gpl);
|
||||
void free_gpencil_layers(struct ListBase *list);
|
||||
void BKE_gpencil_free(struct bGPdata *gpd);
|
||||
void free_gpencil_brushes(struct ListBase *list);
|
||||
void free_gpencil_palettes(struct ListBase *list);
|
||||
void BKE_gpencil_free(struct bGPdata *gpd, bool free_palettes);
|
||||
|
||||
void gpencil_stroke_sync_selection(struct bGPDstroke *gps);
|
||||
|
||||
@@ -52,17 +58,26 @@ struct bGPDframe *gpencil_frame_addcopy(struct bGPDlayer *gpl, int cframe);
|
||||
struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd, const char *name, bool setactive);
|
||||
struct bGPdata *gpencil_data_addnew(const char name[]);
|
||||
|
||||
struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src);
|
||||
struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src);
|
||||
struct bGPDframe *gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
|
||||
struct bGPDlayer *gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
|
||||
struct bGPdata *gpencil_data_duplicate(struct Main *bmain, struct bGPdata *gpd, bool internal_copy);
|
||||
|
||||
void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
|
||||
|
||||
void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
|
||||
|
||||
struct bGPDpalette *gpencil_palette_addnew(struct bGPdata *gpd, const char *name, bool setactive);
|
||||
struct bGPDpalette *gpencil_palette_duplicate(const struct bGPDpalette *palette_src);
|
||||
struct bGPDpalettecolor *gpencil_palettecolor_addnew(struct bGPDpalette *palette, const char *name, bool setactive);
|
||||
|
||||
struct bGPDbrush *gpencil_brush_addnew(struct ToolSettings *ts, const char *name, bool setactive);
|
||||
struct bGPDbrush *gpencil_brush_duplicate(const struct bGPDbrush *brush_src);
|
||||
void gpencil_brush_init_presets(struct ToolSettings *ts);
|
||||
|
||||
|
||||
/* Stroke and Fill - Alpha Visibility Threshold */
|
||||
#define GPENCIL_ALPHA_OPACITY_THRESH 0.001f
|
||||
#define GPENCIL_STRENGTH_MIN 0.003f
|
||||
|
||||
bool gpencil_layer_is_editable(const struct bGPDlayer *gpl);
|
||||
|
||||
@@ -87,4 +102,20 @@ struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd);
|
||||
void gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
|
||||
void gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl);
|
||||
|
||||
struct bGPDbrush *gpencil_brush_getactive(struct ToolSettings *ts);
|
||||
void gpencil_brush_setactive(struct ToolSettings *ts, struct bGPDbrush *active);
|
||||
void gpencil_brush_delete(struct ToolSettings *ts, struct bGPDbrush *palette);
|
||||
|
||||
struct bGPDpalette *gpencil_palette_getactive(struct bGPdata *gpd);
|
||||
void gpencil_palette_setactive(struct bGPdata *gpd, struct bGPDpalette *active);
|
||||
void gpencil_palette_delete(struct bGPdata *gpd, struct bGPDpalette *palette);
|
||||
void gpencil_palette_change_strokes(struct bGPdata *gpd);
|
||||
|
||||
struct bGPDpalettecolor *gpencil_palettecolor_getactive(struct bGPDpalette *palette);
|
||||
void gpencil_palettecolor_setactive(struct bGPDpalette *palette, struct bGPDpalettecolor *active);
|
||||
void gpencil_palettecolor_delete(struct bGPDpalette *palette, struct bGPDpalettecolor *palcolor);
|
||||
struct bGPDpalettecolor *gpencil_palettecolor_getbyname(struct bGPDpalette *palette, char *name);
|
||||
void gpencil_palettecolor_changename(struct bGPdata *gpd, char *oldname, const char *newname);
|
||||
void gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name);
|
||||
|
||||
#endif /* __BKE_GPENCIL_H__ */
|
||||
|
||||
@@ -1112,6 +1112,21 @@ bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C)
|
||||
return ctx_data_pointer_get(C, "active_gpencil_layer");
|
||||
}
|
||||
|
||||
bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, "active_gpencil_palette");
|
||||
}
|
||||
|
||||
bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, "active_gpencil_palettecolor");
|
||||
}
|
||||
|
||||
bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, "active_gpencil_brush");
|
||||
}
|
||||
|
||||
bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
|
||||
{
|
||||
return ctx_data_pointer_get(C, "active_gpencil_frame");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -44,10 +44,12 @@
|
||||
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
@@ -57,21 +59,34 @@
|
||||
|
||||
/* --------- Memory Management ------------ */
|
||||
|
||||
/* free stroke, doesn't unlink from any listbase */
|
||||
void free_gpencil_stroke(bGPDstroke *gps)
|
||||
{
|
||||
if (gps == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free stroke memory arrays, then stroke itself */
|
||||
if (gps->points)
|
||||
MEM_freeN(gps->points);
|
||||
if (gps->triangles)
|
||||
MEM_freeN(gps->triangles);
|
||||
|
||||
MEM_freeN(gps);
|
||||
}
|
||||
|
||||
/* Free strokes belonging to a gp-frame */
|
||||
bool free_gpencil_strokes(bGPDframe *gpf)
|
||||
{
|
||||
bGPDstroke *gps, *gpsn;
|
||||
bGPDstroke *gps_next;
|
||||
bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false);
|
||||
|
||||
/* free strokes */
|
||||
for (gps = gpf->strokes.first; gps; gps = gpsn) {
|
||||
gpsn = gps->next;
|
||||
|
||||
/* free stroke memory arrays, then stroke itself */
|
||||
if (gps->points) MEM_freeN(gps->points);
|
||||
if (gps->triangles) MEM_freeN(gps->triangles);
|
||||
BLI_freelinkN(&gpf->strokes, gps);
|
||||
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps_next) {
|
||||
gps_next = gps->next;
|
||||
free_gpencil_stroke(gps);
|
||||
}
|
||||
BLI_listbase_clear(&gpf->strokes);
|
||||
|
||||
return changed;
|
||||
}
|
||||
@@ -79,14 +94,14 @@ bool free_gpencil_strokes(bGPDframe *gpf)
|
||||
/* Free all of a gp-layer's frames */
|
||||
void free_gpencil_frames(bGPDlayer *gpl)
|
||||
{
|
||||
bGPDframe *gpf, *gpfn;
|
||||
bGPDframe *gpf_next;
|
||||
|
||||
/* error checking */
|
||||
if (gpl == NULL) return;
|
||||
|
||||
/* free frames */
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
|
||||
gpfn = gpf->next;
|
||||
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf_next) {
|
||||
gpf_next = gpf->next;
|
||||
|
||||
/* free strokes and their associated memory */
|
||||
free_gpencil_strokes(gpf);
|
||||
@@ -95,17 +110,79 @@ void free_gpencil_frames(bGPDlayer *gpl)
|
||||
gpl->actframe = NULL;
|
||||
}
|
||||
|
||||
/* Free all of a gp-colors */
|
||||
static void free_gpencil_colors(bGPDpalette *palette)
|
||||
{
|
||||
/* error checking */
|
||||
if (palette == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free colors */
|
||||
BLI_freelistN(&palette->colors);
|
||||
}
|
||||
|
||||
/* Free all of the gp-palettes and colors */
|
||||
void free_gpencil_palettes(ListBase *list)
|
||||
{
|
||||
bGPDpalette *palette_next;
|
||||
|
||||
/* error checking */
|
||||
if (list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* delete palettes */
|
||||
for (bGPDpalette *palette = list->first; palette; palette = palette_next) {
|
||||
palette_next = palette->next;
|
||||
/* free palette colors */
|
||||
free_gpencil_colors(palette);
|
||||
|
||||
MEM_freeN(palette);
|
||||
}
|
||||
BLI_listbase_clear(list);
|
||||
}
|
||||
|
||||
/* Free all of the gp-brushes for a viewport (list should be &gpd->brushes or so) */
|
||||
void free_gpencil_brushes(ListBase *list)
|
||||
{
|
||||
bGPDbrush *brush_next;
|
||||
|
||||
/* error checking */
|
||||
if (list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* delete brushes */
|
||||
for (bGPDbrush *brush = list->first; brush; brush = brush_next) {
|
||||
brush_next = brush->next;
|
||||
/* free curves */
|
||||
if (brush->cur_sensitivity) {
|
||||
curvemapping_free(brush->cur_sensitivity);
|
||||
}
|
||||
if (brush->cur_strength) {
|
||||
curvemapping_free(brush->cur_strength);
|
||||
}
|
||||
if (brush->cur_jitter) {
|
||||
curvemapping_free(brush->cur_jitter);
|
||||
}
|
||||
|
||||
MEM_freeN(brush);
|
||||
}
|
||||
BLI_listbase_clear(list);
|
||||
}
|
||||
|
||||
/* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */
|
||||
void free_gpencil_layers(ListBase *list)
|
||||
{
|
||||
bGPDlayer *gpl, *gpln;
|
||||
bGPDlayer *gpl_next;
|
||||
|
||||
/* error checking */
|
||||
if (list == NULL) return;
|
||||
|
||||
/* delete layers */
|
||||
for (gpl = list->first; gpl; gpl = gpln) {
|
||||
gpln = gpl->next;
|
||||
for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
|
||||
gpl_next = gpl->next;
|
||||
|
||||
/* free layers and their data */
|
||||
free_gpencil_frames(gpl);
|
||||
@@ -113,14 +190,18 @@ void free_gpencil_layers(ListBase *list)
|
||||
}
|
||||
}
|
||||
|
||||
/* Free all of GPencil datablock's related data, but not the block itself */
|
||||
/** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */
|
||||
void BKE_gpencil_free(bGPdata *gpd)
|
||||
void BKE_gpencil_free(bGPdata *gpd, bool free_palettes)
|
||||
{
|
||||
BKE_animdata_free(&gpd->id, false);
|
||||
|
||||
/* free layers */
|
||||
free_gpencil_layers(&gpd->layers);
|
||||
|
||||
/* free palettes */
|
||||
if (free_palettes) {
|
||||
free_gpencil_palettes(&gpd->palettes);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------- Container Creation ---------- */
|
||||
@@ -180,7 +261,7 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
|
||||
/* add a copy of the active gp-frame to the given layer */
|
||||
bGPDframe *gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
|
||||
{
|
||||
bGPDframe *new_frame, *gpf;
|
||||
bGPDframe *new_frame;
|
||||
bool found = false;
|
||||
|
||||
/* Error checking/handling */
|
||||
@@ -197,7 +278,7 @@ bGPDframe *gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
|
||||
new_frame = gpencil_frame_duplicate(gpl->actframe);
|
||||
|
||||
/* Find frame to insert it before */
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
if (gpf->framenum > cframe) {
|
||||
/* Add it here */
|
||||
BLI_insertlinkbefore(&gpl->frames, gpf, new_frame);
|
||||
@@ -249,7 +330,10 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setactive)
|
||||
|
||||
/* set basic settings */
|
||||
copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
|
||||
gpl->thickness = 3;
|
||||
/* Since GPv2 thickness must be 0 */
|
||||
gpl->thickness = 0;
|
||||
|
||||
gpl->opacity = 1.0f;
|
||||
|
||||
/* onion-skinning settings */
|
||||
if (gpd->flag & GP_DATA_SHOW_ONIONSKINS)
|
||||
@@ -263,9 +347,6 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setactive)
|
||||
/* high quality fill by default */
|
||||
gpl->flag |= GP_LAYER_HQ_FILL;
|
||||
|
||||
/* default smooth iterations */
|
||||
gpl->draw_smoothlvl = 1;
|
||||
|
||||
/* auto-name */
|
||||
BLI_strncpy(gpl->info, name, sizeof(gpl->info));
|
||||
BLI_uniquename(&gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
|
||||
@@ -278,6 +359,266 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setactive)
|
||||
return gpl;
|
||||
}
|
||||
|
||||
/* add a new gp-palette and make it the active */
|
||||
bGPDpalette *gpencil_palette_addnew(bGPdata *gpd, const char *name, bool setactive)
|
||||
{
|
||||
bGPDpalette *palette;
|
||||
|
||||
/* check that list is ok */
|
||||
if (gpd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate memory and add to end of list */
|
||||
palette = MEM_callocN(sizeof(bGPDpalette), "bGPDpalette");
|
||||
|
||||
/* add to datablock */
|
||||
BLI_addtail(&gpd->palettes, palette);
|
||||
|
||||
/* set basic settings */
|
||||
/* auto-name */
|
||||
BLI_strncpy(palette->info, name, sizeof(palette->info));
|
||||
BLI_uniquename(&gpd->palettes, palette, DATA_("GP_Palette"), '.', offsetof(bGPDpalette, info),
|
||||
sizeof(palette->info));
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
gpencil_palette_setactive(gpd, palette);
|
||||
}
|
||||
|
||||
/* return palette */
|
||||
return palette;
|
||||
}
|
||||
|
||||
/* create a set of default drawing brushes with predefined presets */
|
||||
void gpencil_brush_init_presets(ToolSettings *ts)
|
||||
{
|
||||
bGPDbrush *brush;
|
||||
/* Basic brush */
|
||||
brush = gpencil_brush_addnew(ts, "Basic", true);
|
||||
brush->thickness = 3.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 1.0f;
|
||||
brush->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 1.0f;
|
||||
brush->flag |= ~GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 0.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = 0.0f;
|
||||
brush->draw_angle_factor = 0.0f;
|
||||
|
||||
brush->draw_smoothfac = 0.0f;
|
||||
brush->draw_smoothlvl = 1;
|
||||
brush->sublevel = 0;
|
||||
brush->draw_random_sub = 0.0f;
|
||||
|
||||
/* Pencil brush */
|
||||
brush = gpencil_brush_addnew(ts, "Pencil", false);
|
||||
brush->thickness = 7.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 1.0f;
|
||||
brush->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 0.7f;
|
||||
brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 0.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = 0.0f;
|
||||
brush->draw_angle_factor = 0.0f;
|
||||
|
||||
brush->draw_smoothfac = 1.0f;
|
||||
brush->draw_smoothlvl = 2;
|
||||
brush->sublevel = 2;
|
||||
brush->draw_random_sub = 0.0f;
|
||||
|
||||
/* Ink brush */
|
||||
brush = gpencil_brush_addnew(ts, "Ink", false);
|
||||
brush->thickness = 7.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 1.6f;
|
||||
brush->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 1.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 0.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = 0.0f;
|
||||
brush->draw_angle_factor = 0.0f;
|
||||
|
||||
brush->draw_smoothfac = 1.1f;
|
||||
brush->draw_smoothlvl = 2;
|
||||
brush->sublevel = 2;
|
||||
brush->draw_random_sub = 0.0f;
|
||||
|
||||
/* Ink Noise brush */
|
||||
brush = gpencil_brush_addnew(ts, "Ink noise", false);
|
||||
brush->thickness = 6.0f;
|
||||
brush->flag |= GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 1.611f;
|
||||
brush->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 1.0f;
|
||||
brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 1.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = 0.0f;
|
||||
brush->draw_angle_factor = 0.0f;
|
||||
|
||||
brush->draw_smoothfac = 1.1f;
|
||||
brush->draw_smoothlvl = 2;
|
||||
brush->sublevel = 2;
|
||||
brush->draw_random_sub = 0.0f;
|
||||
|
||||
/* Marker brush */
|
||||
brush = gpencil_brush_addnew(ts, "Marker", false);
|
||||
brush->thickness = 10.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 2.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 1.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 0.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = M_PI_4; /* 45 degrees */
|
||||
brush->draw_angle_factor = 1.0f;
|
||||
|
||||
brush->draw_smoothfac = 1.0f;
|
||||
brush->draw_smoothlvl = 2;
|
||||
brush->sublevel = 2;
|
||||
brush->draw_random_sub = 0.0f;
|
||||
|
||||
/* Crayon brush */
|
||||
brush = gpencil_brush_addnew(ts, "Crayon", false);
|
||||
brush->thickness = 10.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE;
|
||||
brush->draw_sensitivity = 3.0f;
|
||||
brush->flag &= ~GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH;
|
||||
brush->draw_strength = 0.140f;
|
||||
brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
|
||||
brush->draw_random_press = 0.0f;
|
||||
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
brush->draw_angle = 0.0f;
|
||||
brush->draw_angle_factor = 0.0f;
|
||||
|
||||
brush->draw_smoothfac = 0.0f;
|
||||
brush->draw_smoothlvl = 1;
|
||||
brush->sublevel = 2;
|
||||
brush->draw_random_sub = 0.5f;
|
||||
|
||||
}
|
||||
|
||||
/* add a new gp-brush and make it the active */
|
||||
bGPDbrush *gpencil_brush_addnew(ToolSettings *ts, const char *name, bool setactive)
|
||||
{
|
||||
bGPDbrush *brush;
|
||||
|
||||
/* check that list is ok */
|
||||
if (ts == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate memory and add to end of list */
|
||||
brush = MEM_callocN(sizeof(bGPDbrush), "bGPDbrush");
|
||||
|
||||
/* add to datablock */
|
||||
BLI_addtail(&ts->gp_brushes, brush);
|
||||
|
||||
/* set basic settings */
|
||||
brush->thickness = 3;
|
||||
brush->draw_smoothlvl = 1;
|
||||
brush->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
brush->draw_sensitivity = 1.0f;
|
||||
brush->draw_strength = 1.0f;
|
||||
brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
|
||||
brush->draw_jitter = 0.0f;
|
||||
brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
|
||||
|
||||
/* curves */
|
||||
brush->cur_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
brush->cur_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
brush->cur_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
/* auto-name */
|
||||
BLI_strncpy(brush->info, name, sizeof(brush->info));
|
||||
BLI_uniquename(&ts->gp_brushes, brush, DATA_("GP_Brush"), '.', offsetof(bGPDbrush, info), sizeof(brush->info));
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
gpencil_brush_setactive(ts, brush);
|
||||
}
|
||||
|
||||
/* return brush */
|
||||
return brush;
|
||||
}
|
||||
|
||||
/* add a new gp-palettecolor and make it the active */
|
||||
bGPDpalettecolor *gpencil_palettecolor_addnew(bGPDpalette *palette, const char *name, bool setactive)
|
||||
{
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
/* check that list is ok */
|
||||
if (palette == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate memory and add to end of list */
|
||||
palcolor = MEM_callocN(sizeof(bGPDpalettecolor), "bGPDpalettecolor");
|
||||
|
||||
/* add to datablock */
|
||||
BLI_addtail(&palette->colors, palcolor);
|
||||
|
||||
/* set basic settings */
|
||||
palcolor->flag |= PC_COLOR_HQ_FILL;
|
||||
copy_v4_v4(palcolor->color, U.gpencil_new_layer_col);
|
||||
ARRAY_SET_ITEMS(palcolor->fill, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
/* auto-name */
|
||||
BLI_strncpy(palcolor->info, name, sizeof(palcolor->info));
|
||||
BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info),
|
||||
sizeof(palcolor->info));
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
gpencil_palettecolor_setactive(palette, palcolor);
|
||||
}
|
||||
|
||||
/* return palette color */
|
||||
return palcolor;
|
||||
}
|
||||
|
||||
/* add a new gp-datablock */
|
||||
bGPdata *gpencil_data_addnew(const char name[])
|
||||
{
|
||||
@@ -300,94 +641,157 @@ bGPdata *gpencil_data_addnew(const char name[])
|
||||
/* -------- Data Duplication ---------- */
|
||||
|
||||
/* make a copy of a given gpencil frame */
|
||||
bGPDframe *gpencil_frame_duplicate(bGPDframe *src)
|
||||
bGPDframe *gpencil_frame_duplicate(const bGPDframe *gpf_src)
|
||||
{
|
||||
bGPDstroke *gps, *gpsd;
|
||||
bGPDframe *dst;
|
||||
bGPDstroke *gps_dst;
|
||||
bGPDframe *gpf_dst;
|
||||
|
||||
/* error checking */
|
||||
if (src == NULL)
|
||||
if (gpf_src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make a copy of the source frame */
|
||||
dst = MEM_dupallocN(src);
|
||||
dst->prev = dst->next = NULL;
|
||||
gpf_dst = MEM_dupallocN(gpf_src);
|
||||
gpf_dst->prev = gpf_dst->next = NULL;
|
||||
|
||||
/* copy strokes */
|
||||
BLI_listbase_clear(&dst->strokes);
|
||||
for (gps = src->strokes.first; gps; gps = gps->next) {
|
||||
BLI_listbase_clear(&gpf_dst->strokes);
|
||||
for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) {
|
||||
/* make copy of source stroke, then adjust pointer to points too */
|
||||
gpsd = MEM_dupallocN(gps);
|
||||
gpsd->points = MEM_dupallocN(gps->points);
|
||||
gpsd->triangles = MEM_dupallocN(gps->triangles);
|
||||
gpsd->flag |= GP_STROKE_RECALC_CACHES;
|
||||
BLI_addtail(&dst->strokes, gpsd);
|
||||
gps_dst = MEM_dupallocN(gps_src);
|
||||
gps_dst->points = MEM_dupallocN(gps_src->points);
|
||||
gps_dst->triangles = MEM_dupallocN(gps_src->triangles);
|
||||
gps_dst->flag |= GP_STROKE_RECALC_CACHES;
|
||||
BLI_addtail(&gpf_dst->strokes, gps_dst);
|
||||
}
|
||||
|
||||
/* return new frame */
|
||||
return dst;
|
||||
return gpf_dst;
|
||||
}
|
||||
|
||||
/* make a copy of a given gpencil layer */
|
||||
bGPDlayer *gpencil_layer_duplicate(bGPDlayer *src)
|
||||
/* make a copy of a given gpencil brush */
|
||||
bGPDbrush *gpencil_brush_duplicate(const bGPDbrush *brush_src)
|
||||
{
|
||||
bGPDframe *gpf, *gpfd;
|
||||
bGPDlayer *dst;
|
||||
bGPDbrush *brush_dst;
|
||||
|
||||
/* error checking */
|
||||
if (src == NULL)
|
||||
if (brush_src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make a copy of source brush */
|
||||
brush_dst = MEM_dupallocN(brush_src);
|
||||
brush_dst->prev = brush_dst->next = NULL;
|
||||
/* make a copy of curves */
|
||||
brush_dst->cur_sensitivity = curvemapping_copy(brush_src->cur_sensitivity);
|
||||
brush_dst->cur_strength = curvemapping_copy(brush_src->cur_strength);
|
||||
brush_dst->cur_jitter = curvemapping_copy(brush_src->cur_jitter);
|
||||
|
||||
/* return new brush */
|
||||
return brush_dst;
|
||||
}
|
||||
|
||||
/* make a copy of a given gpencil palette */
|
||||
bGPDpalette *gpencil_palette_duplicate(const bGPDpalette *palette_src)
|
||||
{
|
||||
bGPDpalette *palette_dst;
|
||||
const bGPDpalettecolor *palcolor_src;
|
||||
bGPDpalettecolor *palcolord_dst;
|
||||
|
||||
/* error checking */
|
||||
if (palette_src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make a copy of source palette */
|
||||
palette_dst = MEM_dupallocN(palette_src);
|
||||
palette_dst->prev = palette_dst->next = NULL;
|
||||
|
||||
/* copy colors */
|
||||
BLI_listbase_clear(&palette_dst->colors);
|
||||
for (palcolor_src = palette_src->colors.first; palcolor_src; palcolor_src = palcolor_src->next) {
|
||||
/* make a copy of source */
|
||||
palcolord_dst = MEM_dupallocN(palcolor_src);
|
||||
BLI_addtail(&palette_dst->colors, palcolord_dst);
|
||||
}
|
||||
|
||||
/* return new palette */
|
||||
return palette_dst;
|
||||
}
|
||||
/* make a copy of a given gpencil layer */
|
||||
bGPDlayer *gpencil_layer_duplicate(const bGPDlayer *gpl_src)
|
||||
{
|
||||
const bGPDframe *gpf_src;
|
||||
bGPDframe *gpf_dst;
|
||||
bGPDlayer *gpl_dst;
|
||||
|
||||
/* error checking */
|
||||
if (gpl_src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make a copy of source layer */
|
||||
dst = MEM_dupallocN(src);
|
||||
dst->prev = dst->next = NULL;
|
||||
gpl_dst = MEM_dupallocN(gpl_src);
|
||||
gpl_dst->prev = gpl_dst->next = NULL;
|
||||
|
||||
/* copy frames */
|
||||
BLI_listbase_clear(&dst->frames);
|
||||
for (gpf = src->frames.first; gpf; gpf = gpf->next) {
|
||||
BLI_listbase_clear(&gpl_dst->frames);
|
||||
for (gpf_src = gpl_src->frames.first; gpf_src; gpf_src = gpf_src->next) {
|
||||
/* make a copy of source frame */
|
||||
gpfd = gpencil_frame_duplicate(gpf);
|
||||
BLI_addtail(&dst->frames, gpfd);
|
||||
gpf_dst = gpencil_frame_duplicate(gpf_src);
|
||||
BLI_addtail(&gpl_dst->frames, gpf_dst);
|
||||
|
||||
/* if source frame was the current layer's 'active' frame, reassign that too */
|
||||
if (gpf == dst->actframe)
|
||||
dst->actframe = gpfd;
|
||||
if (gpf_src == gpl_dst->actframe)
|
||||
gpl_dst->actframe = gpf_dst;
|
||||
}
|
||||
|
||||
/* return new layer */
|
||||
return dst;
|
||||
return gpl_dst;
|
||||
}
|
||||
|
||||
/* make a copy of a given gpencil datablock */
|
||||
bGPdata *gpencil_data_duplicate(Main *bmain, bGPdata *src, bool internal_copy)
|
||||
bGPdata *gpencil_data_duplicate(Main *bmain, bGPdata *gpd_src, bool internal_copy)
|
||||
{
|
||||
bGPDlayer *gpl, *gpld;
|
||||
bGPdata *dst;
|
||||
const bGPDlayer *gpl_src;
|
||||
bGPDlayer *gpl_dst;
|
||||
bGPdata *gpd_dst;
|
||||
|
||||
/* error checking */
|
||||
if (src == NULL)
|
||||
if (gpd_src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make a copy of the base-data */
|
||||
if (internal_copy) {
|
||||
/* make a straight copy for undo buffers used during stroke drawing */
|
||||
dst = MEM_dupallocN(src);
|
||||
gpd_dst = MEM_dupallocN(gpd_src);
|
||||
}
|
||||
else {
|
||||
/* make a copy when others use this */
|
||||
dst = BKE_libblock_copy(bmain, &src->id);
|
||||
gpd_dst = BKE_libblock_copy(bmain, &gpd_src->id);
|
||||
}
|
||||
|
||||
/* copy layers */
|
||||
BLI_listbase_clear(&dst->layers);
|
||||
for (gpl = src->layers.first; gpl; gpl = gpl->next) {
|
||||
BLI_listbase_clear(&gpd_dst->layers);
|
||||
for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
|
||||
/* make a copy of source layer and its data */
|
||||
gpld = gpencil_layer_duplicate(gpl);
|
||||
BLI_addtail(&dst->layers, gpld);
|
||||
gpl_dst = gpencil_layer_duplicate(gpl_src);
|
||||
BLI_addtail(&gpd_dst->layers, gpl_dst);
|
||||
}
|
||||
if (!internal_copy) {
|
||||
/* copy palettes */
|
||||
bGPDpalette *palette_src, *palette_dst;
|
||||
BLI_listbase_clear(&gpd_dst->palettes);
|
||||
for (palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) {
|
||||
palette_dst = gpencil_palette_duplicate(palette_src);
|
||||
BLI_addtail(&gpd_dst->palettes, palette_dst);
|
||||
}
|
||||
}
|
||||
|
||||
/* return new */
|
||||
return dst;
|
||||
return gpd_dst;
|
||||
}
|
||||
|
||||
void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local)
|
||||
@@ -458,7 +862,7 @@ bool gpencil_layer_is_editable(const bGPDlayer *gpl)
|
||||
/* Opacity must be sufficiently high that it is still "visible"
|
||||
* Otherwise, it's not really "visible" to the user, so no point editing...
|
||||
*/
|
||||
if ((gpl->color[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gpl->fill[3] > GPENCIL_ALPHA_OPACITY_THRESH)) {
|
||||
if (gpl->opacity > GPENCIL_ALPHA_OPACITY_THRESH) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -685,3 +1089,243 @@ void gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* get the active gp-brush for editing */
|
||||
bGPDbrush *gpencil_brush_getactive(ToolSettings *ts)
|
||||
{
|
||||
bGPDbrush *brush;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, ts, ts->gp_brushes.first)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* loop over brushes until found (assume only one active) */
|
||||
for (brush = ts->gp_brushes.first; brush; brush = brush->next) {
|
||||
if (brush->flag & GP_BRUSH_ACTIVE) {
|
||||
return brush;
|
||||
}
|
||||
}
|
||||
|
||||
/* no active brush found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the active gp-brush */
|
||||
void gpencil_brush_setactive(ToolSettings *ts, bGPDbrush *active)
|
||||
{
|
||||
bGPDbrush *brush;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, ts, ts->gp_brushes.first, active)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* loop over brushes deactivating all */
|
||||
for (brush = ts->gp_brushes.first; brush; brush = brush->next) {
|
||||
brush->flag &= ~GP_BRUSH_ACTIVE;
|
||||
}
|
||||
|
||||
/* set as active one */
|
||||
active->flag |= GP_BRUSH_ACTIVE;
|
||||
}
|
||||
|
||||
/* delete the active gp-brush */
|
||||
void gpencil_brush_delete(ToolSettings *ts, bGPDbrush *brush)
|
||||
{
|
||||
/* error checking */
|
||||
if (ELEM(NULL, ts, brush)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free curves */
|
||||
if (brush->cur_sensitivity) {
|
||||
curvemapping_free(brush->cur_sensitivity);
|
||||
}
|
||||
if (brush->cur_strength) {
|
||||
curvemapping_free(brush->cur_strength);
|
||||
}
|
||||
if (brush->cur_jitter) {
|
||||
curvemapping_free(brush->cur_jitter);
|
||||
}
|
||||
|
||||
/* free */
|
||||
BLI_freelinkN(&ts->gp_brushes, brush);
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* get the active gp-palette for editing */
|
||||
bGPDpalette *gpencil_palette_getactive(bGPdata *gpd)
|
||||
{
|
||||
bGPDpalette *palette;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, gpd, gpd->palettes.first)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* loop over palettes until found (assume only one active) */
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
if (palette->flag & PL_PALETTE_ACTIVE)
|
||||
return palette;
|
||||
}
|
||||
|
||||
/* no active palette found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the active gp-palette */
|
||||
void gpencil_palette_setactive(bGPdata *gpd, bGPDpalette *active)
|
||||
{
|
||||
bGPDpalette *palette;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, gpd, gpd->palettes.first, active)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* loop over palettes deactivating all */
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
palette->flag &= ~PL_PALETTE_ACTIVE;
|
||||
}
|
||||
|
||||
/* set as active one */
|
||||
active->flag |= PL_PALETTE_ACTIVE;
|
||||
/* force color recalc */
|
||||
gpencil_palette_change_strokes(gpd);
|
||||
}
|
||||
|
||||
/* delete the active gp-palette */
|
||||
void gpencil_palette_delete(bGPdata *gpd, bGPDpalette *palette)
|
||||
{
|
||||
/* error checking */
|
||||
if (ELEM(NULL, gpd, palette)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free colors */
|
||||
free_gpencil_colors(palette);
|
||||
BLI_freelinkN(&gpd->palettes, palette);
|
||||
/* force color recalc */
|
||||
gpencil_palette_change_strokes(gpd);
|
||||
}
|
||||
|
||||
/* Set all strokes to recalc the palette color */
|
||||
void gpencil_palette_change_strokes(bGPdata *gpd)
|
||||
{
|
||||
bGPDlayer *gpl;
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
gps->flag |= GP_STROKE_RECALC_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* get the active gp-palettecolor for editing */
|
||||
bGPDpalettecolor *gpencil_palettecolor_getactive(bGPDpalette *palette)
|
||||
{
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, palette, palette->colors.first)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* loop over colors until found (assume only one active) */
|
||||
for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
|
||||
if (palcolor->flag & PC_COLOR_ACTIVE) {
|
||||
return palcolor;
|
||||
}
|
||||
}
|
||||
|
||||
/* no active color found */
|
||||
return NULL;
|
||||
}
|
||||
/* get the gp-palettecolor looking for name */
|
||||
bGPDpalettecolor *gpencil_palettecolor_getbyname(bGPDpalette *palette, char *name)
|
||||
{
|
||||
/* error checking */
|
||||
if (ELEM(NULL, palette, name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BLI_findstring(&palette->colors, name, offsetof(bGPDpalettecolor, info));
|
||||
}
|
||||
|
||||
/* Change color name in all strokes */
|
||||
void gpencil_palettecolor_changename(bGPdata *gpd, char *oldname, const char *newname)
|
||||
{
|
||||
bGPDlayer *gpl;
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
if (STREQ(gps->colorname, oldname)) {
|
||||
strcpy(gps->colorname, newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Delete all strokes of the color */
|
||||
void gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name)
|
||||
{
|
||||
bGPDlayer *gpl;
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps, *gpsn;
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (gps = gpf->strokes.first; gps; gps = gpsn) {
|
||||
gpsn = gps->next;
|
||||
|
||||
if (STREQ(gps->colorname, name)) {
|
||||
if (gps->points) MEM_freeN(gps->points);
|
||||
if (gps->triangles) MEM_freeN(gps->triangles);
|
||||
BLI_freelinkN(&gpf->strokes, gps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* set the active gp-palettecolor */
|
||||
void gpencil_palettecolor_setactive(bGPDpalette *palette, bGPDpalettecolor *active)
|
||||
{
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, palette, palette->colors.first, active)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* loop over colors deactivating all */
|
||||
for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
|
||||
palcolor->flag &= ~PC_COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
/* set as active one */
|
||||
active->flag |= PC_COLOR_ACTIVE;
|
||||
}
|
||||
|
||||
/* delete the active gp-palettecolor */
|
||||
void gpencil_palettecolor_delete(bGPDpalette *palette, bGPDpalettecolor *palcolor)
|
||||
{
|
||||
/* error checking */
|
||||
if (ELEM(NULL, palette, palcolor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* free */
|
||||
BLI_freelinkN(&palette->colors, palcolor);
|
||||
}
|
||||
|
||||
@@ -795,7 +795,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user)
|
||||
free_windowmanager_cb(NULL, (wmWindowManager *)id);
|
||||
break;
|
||||
case ID_GD:
|
||||
BKE_gpencil_free((bGPdata *)id);
|
||||
BKE_gpencil_free((bGPdata *)id, true);
|
||||
break;
|
||||
case ID_MC:
|
||||
BKE_movieclip_free((MovieClip *)id);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
@@ -286,6 +287,13 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
ts->imapaint.paintcursor = NULL;
|
||||
id_us_plus((ID *)ts->imapaint.stencil);
|
||||
ts->particle.paintcursor = NULL;
|
||||
/* duplicate Grease Pencil Drawing Brushes */
|
||||
BLI_listbase_clear(&ts->gp_brushes);
|
||||
for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
|
||||
bGPDbrush *newbrush = gpencil_brush_duplicate(brush);
|
||||
BLI_addtail(&ts->gp_brushes, newbrush);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* make a private copy of the avicodecdata */
|
||||
@@ -432,6 +440,10 @@ void BKE_scene_free(Scene *sce)
|
||||
BKE_paint_free(&sce->toolsettings->uvsculpt->paint);
|
||||
MEM_freeN(sce->toolsettings->uvsculpt);
|
||||
}
|
||||
/* free Grease Pencil Drawing Brushes */
|
||||
free_gpencil_brushes(&sce->toolsettings->gp_brushes);
|
||||
BLI_freelistN(&sce->toolsettings->gp_brushes);
|
||||
|
||||
BKE_paint_free(&sce->toolsettings->imapaint.paint);
|
||||
|
||||
MEM_freeN(sce->toolsettings);
|
||||
@@ -764,6 +776,11 @@ void BKE_scene_init(Scene *sce)
|
||||
gp_brush->strength = 0.5f;
|
||||
gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
|
||||
|
||||
gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH];
|
||||
gp_brush->size = 25;
|
||||
gp_brush->strength = 0.5f;
|
||||
gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
|
||||
|
||||
gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB];
|
||||
gp_brush->size = 50;
|
||||
gp_brush->strength = 0.3f;
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_outliner_treehash.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
#include "NOD_common.h"
|
||||
#include "NOD_socket.h"
|
||||
@@ -5872,6 +5872,22 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
sce->toolsettings->wpaint->wpaint_prev = NULL;
|
||||
sce->toolsettings->wpaint->tot = 0;
|
||||
}
|
||||
/* relink grease pencil drawing brushes */
|
||||
link_list(fd, &sce->toolsettings->gp_brushes);
|
||||
for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
|
||||
brush->cur_sensitivity = newdataadr(fd, brush->cur_sensitivity);
|
||||
if (brush->cur_sensitivity) {
|
||||
direct_link_curvemapping(fd, brush->cur_sensitivity);
|
||||
}
|
||||
brush->cur_strength = newdataadr(fd, brush->cur_strength);
|
||||
if (brush->cur_strength) {
|
||||
direct_link_curvemapping(fd, brush->cur_strength);
|
||||
}
|
||||
brush->cur_jitter = newdataadr(fd, brush->cur_jitter);
|
||||
if (brush->cur_jitter) {
|
||||
direct_link_curvemapping(fd, brush->cur_jitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sce->ed) {
|
||||
@@ -6154,6 +6170,7 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
|
||||
bGPDlayer *gpl;
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
bGPDpalette *palette;
|
||||
|
||||
/* we must firstly have some grease-pencil data to link! */
|
||||
if (gpd == NULL)
|
||||
@@ -6163,10 +6180,18 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
|
||||
gpd->adt = newdataadr(fd, gpd->adt);
|
||||
direct_link_animdata(fd, gpd->adt);
|
||||
|
||||
/* relink palettes */
|
||||
link_list(fd, &gpd->palettes);
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
link_list(fd, &palette->colors);
|
||||
}
|
||||
|
||||
/* relink layers */
|
||||
link_list(fd, &gpd->layers);
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* parent */
|
||||
gpl->parent = newlibadr(fd, gpd->id.lib, gpl->parent);
|
||||
/* relink frames */
|
||||
link_list(fd, &gpl->frames);
|
||||
gpl->actframe = newdataadr(fd, gpl->actframe);
|
||||
@@ -6179,9 +6204,12 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
|
||||
gps->points = newdataadr(fd, gps->points);
|
||||
|
||||
/* the triangulation is not saved, so need to be recalculated */
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
gps->triangles = NULL;
|
||||
gps->tot_triangles = 0;
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
/* the color pointer is not saved, so need to be recalculated using the color name */
|
||||
gps->palcolor = NULL;
|
||||
gps->flag |= GP_STROKE_RECALC_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_gpencil.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_listbase.h"
|
||||
@@ -1075,15 +1076,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
/* init grease pencil smooth level iterations */
|
||||
for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
if (gpl->draw_smoothlvl == 0) {
|
||||
gpl->draw_smoothlvl = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
@@ -1192,7 +1184,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
|
||||
for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) {
|
||||
if (camera->stereo.pole_merge_angle_from == 0.0f &&
|
||||
camera->stereo.pole_merge_angle_to == 0.0f)
|
||||
camera->stereo.pole_merge_angle_to == 0.0f)
|
||||
{
|
||||
camera->stereo.pole_merge_angle_from = DEG2RADF(60.0f);
|
||||
camera->stereo.pole_merge_angle_to = DEG2RADF(75.0f);
|
||||
@@ -1251,4 +1243,82 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(main, 277, 3)) {
|
||||
/* ------- init of grease pencil initialization --------------- */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPDstroke", "bGPDpalettecolor", "palcolor")) {
|
||||
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
/* initialize use position for sculpt brushes */
|
||||
ts->gp_sculpt.flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
|
||||
/* initialize selected vertices alpha factor */
|
||||
ts->gp_sculpt.alpha = 1.0f;
|
||||
|
||||
/* new strength sculpt brush */
|
||||
if (ts->gp_sculpt.brush[0].size >= 11) {
|
||||
GP_BrushEdit_Settings *gset = &ts->gp_sculpt;
|
||||
GP_EditBrush_Data *brush;
|
||||
|
||||
brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH];
|
||||
brush->size = 25;
|
||||
brush->strength = 0.5f;
|
||||
brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
|
||||
}
|
||||
}
|
||||
/* create a default grease pencil drawing brushes set */
|
||||
if (!BLI_listbase_is_empty(&main->gpencil)) {
|
||||
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
if (BLI_listbase_is_empty(&ts->gp_brushes)) {
|
||||
gpencil_brush_init_presets(ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Convert Grease Pencil to new palettes/brushes
|
||||
* Loop all strokes and create the palette and all colors
|
||||
*/
|
||||
for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
|
||||
if (BLI_listbase_is_empty(&gpd->palettes)) {
|
||||
/* create palette */
|
||||
bGPDpalette *palette = gpencil_palette_addnew(gpd, "GP_Palette", true);
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* create color using layer name */
|
||||
bGPDpalettecolor *palcolor = gpencil_palettecolor_addnew(palette, gpl->info, true);
|
||||
if (palcolor != NULL) {
|
||||
/* set color attributes */
|
||||
copy_v4_v4(palcolor->color, gpl->color);
|
||||
copy_v4_v4(palcolor->fill, gpl->fill);
|
||||
palcolor->flag = gpl->flag;
|
||||
/* set layer opacity to 1 */
|
||||
gpl->opacity = 1.0f;
|
||||
/* set tint color */
|
||||
ARRAY_SET_ITEMS(gpl->tintcolor, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* set stroke to palette and force recalculation */
|
||||
strcpy(gps->colorname, gpl->info);
|
||||
gps->palcolor = NULL;
|
||||
gps->flag |= GP_STROKE_RECALC_COLOR;
|
||||
gps->thickness = gpl->thickness;
|
||||
/* set alpha strength to 1 */
|
||||
for (int i = 0; i < gps->totpoints; i++) {
|
||||
gps->points[i].strength = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
/* set thickness to 0 (now it is a factor to override stroke thickness) */
|
||||
gpl->thickness = 0.0f;
|
||||
}
|
||||
/* set first color as active */
|
||||
if (palette->colors.first)
|
||||
gpencil_palettecolor_setactive(palette, palette->colors.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ------- end of grease pencil initialization --------------- */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,6 +108,11 @@ void BLO_update_defaults_startup_blend(Main *bmain)
|
||||
brush->strength = 0.5f;
|
||||
brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
|
||||
|
||||
brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH];
|
||||
brush->size = 25;
|
||||
brush->strength = 0.5f;
|
||||
brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF;
|
||||
|
||||
brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB];
|
||||
brush->size = 50;
|
||||
brush->strength = 0.3f;
|
||||
|
||||
@@ -2673,6 +2673,20 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
|
||||
writestruct(wd, DATA, UvSculpt, 1, tos->uvsculpt);
|
||||
write_paint(wd, &tos->uvsculpt->paint);
|
||||
}
|
||||
/* write grease-pencil drawing brushes to file */
|
||||
writelist(wd, DATA, bGPDbrush, &tos->gp_brushes);
|
||||
for (bGPDbrush *brush = tos->gp_brushes.first; brush; brush = brush->next) {
|
||||
if (brush->cur_sensitivity) {
|
||||
write_curvemapping(wd, brush->cur_sensitivity);
|
||||
}
|
||||
if (brush->cur_strength) {
|
||||
write_curvemapping(wd, brush->cur_strength);
|
||||
}
|
||||
if (brush->cur_jitter) {
|
||||
write_curvemapping(wd, brush->cur_jitter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
write_paint(wd, &tos->imapaint.paint);
|
||||
|
||||
@@ -2835,6 +2849,7 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
|
||||
bGPDlayer *gpl;
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
bGPDpalette *palette;
|
||||
|
||||
for (gpd = lb->first; gpd; gpd = gpd->id.next) {
|
||||
if (gpd->id.us > 0 || wd->current) {
|
||||
@@ -2861,6 +2876,11 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* write grease-pencil palettes */
|
||||
writelist(wd, DATA, bGPDpalette, &gpd->palettes);
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
writelist(wd, DATA, bGPDpalettecolor, &palette->colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4208,6 +4208,8 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
|
||||
offset += ICON_WIDTH;
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
#if 0
|
||||
/* XXX: Maybe need a better design */
|
||||
/* color swatch for layer color */
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
PointerRNA ptr;
|
||||
@@ -4216,7 +4218,6 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
|
||||
RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
|
||||
|
||||
UI_block_align_begin(block);
|
||||
|
||||
UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
|
||||
uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
|
||||
&ptr, "color", -1,
|
||||
@@ -4226,11 +4227,11 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
|
||||
uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
|
||||
&ptr, "fill_color", -1,
|
||||
0, 0, 0, 0, gpl->info);
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
UI_block_align_end(block);
|
||||
|
||||
offset += ICON_WIDTH;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
* The Original Code is Copyright (C) 2015, Blender Foundation
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -223,9 +224,26 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i
|
||||
GP_EditBrush_Data *brush = gso->brush;
|
||||
float inf = gp_brush_influence_calc(gso, radius, co);
|
||||
bool affect_pressure = (brush->flag & GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE) != 0;
|
||||
/* need one flag enabled by default */
|
||||
if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
|
||||
GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
|
||||
GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0)
|
||||
{
|
||||
gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
|
||||
}
|
||||
|
||||
/* perform smoothing */
|
||||
return gp_smooth_stroke(gps, i, inf, affect_pressure);
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_POSITION) {
|
||||
gp_smooth_stroke(gps, i, inf, affect_pressure);
|
||||
}
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_STRENGTH) {
|
||||
gp_smooth_stroke_strength(gps, i, inf);
|
||||
}
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) {
|
||||
gp_smooth_stroke_thickness(gps, i, inf);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
@@ -267,6 +285,41 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Color Strength Brush */
|
||||
|
||||
/* Make color more or less transparent by the specified amounts */
|
||||
static bool gp_brush_strength_apply(
|
||||
tGP_BrushEditData *gso, bGPDstroke *gps, int i,
|
||||
const int radius, const int co[2])
|
||||
{
|
||||
bGPDspoint *pt = gps->points + i;
|
||||
float inf;
|
||||
|
||||
/* Compute strength of effect
|
||||
* - We divide the strength by 10, so that users can set "sane" values.
|
||||
* Otherwise, good default values are in the range of 0.093
|
||||
*/
|
||||
inf = gp_brush_influence_calc(gso, radius, co) / 10.0f;
|
||||
|
||||
/* apply */
|
||||
// XXX: this is much too strong, and it should probably do some smoothing with the surrounding stuff
|
||||
if (gp_brush_invert_check(gso)) {
|
||||
/* make line thinner - reduce stroke pressure */
|
||||
pt->strength -= inf;
|
||||
}
|
||||
else {
|
||||
/* make line thicker - increase stroke pressure */
|
||||
pt->strength += inf;
|
||||
}
|
||||
|
||||
/* Strength should stay within [0.0, 1.0] */
|
||||
CLAMP(pt->strength, 0.0f, 1.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Grab Brush */
|
||||
|
||||
@@ -373,7 +426,8 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso)
|
||||
}
|
||||
|
||||
/* Apply grab transform to all relevant points of the affected strokes */
|
||||
static void gp_brush_grab_apply_cached(tGP_BrushEditData *gso, bGPDstroke *gps)
|
||||
static void gp_brush_grab_apply_cached(
|
||||
tGP_BrushEditData *gso, bGPDstroke *gps, bool parented, float diff_mat[4][4])
|
||||
{
|
||||
tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
|
||||
int i;
|
||||
@@ -385,9 +439,23 @@ static void gp_brush_grab_apply_cached(tGP_BrushEditData *gso, bGPDstroke *gps)
|
||||
|
||||
/* adjust the amount of displacement to apply */
|
||||
mul_v3_v3fl(delta, gso->dvec, data->weights[i]);
|
||||
if (!parented) {
|
||||
/* apply */
|
||||
add_v3_v3(&pt->x, delta);
|
||||
}
|
||||
else {
|
||||
float fpt[3];
|
||||
/* apply transformation */
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
/* apply */
|
||||
add_v3_v3(fpt, delta);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
/* undo transformation to the init parent position */
|
||||
float inverse_diff_mat[4][4];
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
mul_m4_v3(inverse_diff_mat, &pt->x);
|
||||
}
|
||||
|
||||
/* apply */
|
||||
add_v3_v3(&pt->x, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,60 +660,90 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
|
||||
*/
|
||||
const float inf = gp_brush_influence_calc(gso, radius, co) / 2.0f;
|
||||
const float fac = BLI_frand() * inf;
|
||||
|
||||
/* Jitter is applied perpendicular to the mouse movement vector
|
||||
* - We compute all effects in screenspace (since it's easier)
|
||||
* and then project these to get the points/distances in
|
||||
* viewspace as needed
|
||||
*/
|
||||
float mvec[2], svec[2];
|
||||
|
||||
/* mouse movement in ints -> floats */
|
||||
mvec[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
|
||||
mvec[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
|
||||
|
||||
/* rotate mvec by 90 degrees... */
|
||||
svec[0] = -mvec[1];
|
||||
svec[1] = mvec[0];
|
||||
|
||||
//printf("svec = %f %f, ", svec[0], svec[1]);
|
||||
|
||||
/* scale the displacement by the random displacement, and apply */
|
||||
if (BLI_frand() > 0.5f) {
|
||||
mul_v2_fl(svec, -fac);
|
||||
}
|
||||
else {
|
||||
mul_v2_fl(svec, fac);
|
||||
/* need one flag enabled by default */
|
||||
if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION |
|
||||
GP_BRUSHEDIT_FLAG_APPLY_STRENGTH |
|
||||
GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0)
|
||||
{
|
||||
gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
|
||||
}
|
||||
|
||||
//printf("%f %f (%f), nco = {%f %f}, co = %d %d\n", svec[0], svec[1], fac, nco[0], nco[1], co[0], co[1]);
|
||||
/* apply random to position */
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_POSITION) {
|
||||
/* Jitter is applied perpendicular to the mouse movement vector
|
||||
* - We compute all effects in screenspace (since it's easier)
|
||||
* and then project these to get the points/distances in
|
||||
* viewspace as needed
|
||||
*/
|
||||
float mvec[2], svec[2];
|
||||
|
||||
/* convert to dataspace */
|
||||
if (gps->flag & GP_STROKE_3DSPACE) {
|
||||
/* 3D: Project to 3D space */
|
||||
if (gso->sa->spacetype == SPACE_VIEW3D) {
|
||||
bool flip;
|
||||
RegionView3D *rv3d = gso->ar->regiondata;
|
||||
float zfac = ED_view3d_calc_zfac(rv3d, &pt->x, &flip);
|
||||
if (flip == false) {
|
||||
float dvec[3];
|
||||
ED_view3d_win_to_delta(gso->gsc.ar, svec, dvec, zfac);
|
||||
add_v3_v3(&pt->x, dvec);
|
||||
/* mouse movement in ints -> floats */
|
||||
mvec[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
|
||||
mvec[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
|
||||
|
||||
/* rotate mvec by 90 degrees... */
|
||||
svec[0] = -mvec[1];
|
||||
svec[1] = mvec[0];
|
||||
|
||||
/* scale the displacement by the random displacement, and apply */
|
||||
if (BLI_frand() > 0.5f) {
|
||||
mul_v2_fl(svec, -fac);
|
||||
}
|
||||
else {
|
||||
mul_v2_fl(svec, fac);
|
||||
}
|
||||
|
||||
//printf("%f %f (%f), nco = {%f %f}, co = %d %d\n", svec[0], svec[1], fac, nco[0], nco[1], co[0], co[1]);
|
||||
|
||||
/* convert to dataspace */
|
||||
if (gps->flag & GP_STROKE_3DSPACE) {
|
||||
/* 3D: Project to 3D space */
|
||||
if (gso->sa->spacetype == SPACE_VIEW3D) {
|
||||
bool flip;
|
||||
RegionView3D *rv3d = gso->ar->regiondata;
|
||||
float zfac = ED_view3d_calc_zfac(rv3d, &pt->x, &flip);
|
||||
if (flip == false) {
|
||||
float dvec[3];
|
||||
ED_view3d_win_to_delta(gso->gsc.ar, svec, dvec, zfac);
|
||||
add_v3_v3(&pt->x, dvec);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* ERROR */
|
||||
BLI_assert("3D stroke being sculpted in non-3D view");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* ERROR */
|
||||
BLI_assert("3D stroke being sculpted in non-3D view");
|
||||
/* 2D: As-is */
|
||||
// XXX: v2d scaling/offset?
|
||||
float nco[2];
|
||||
nco[0] = (float)co[0] + svec[0];
|
||||
nco[1] = (float)co[1] + svec[1];
|
||||
|
||||
copy_v2_v2(&pt->x, nco);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* 2D: As-is */
|
||||
// XXX: v2d scaling/offset?
|
||||
float nco[2];
|
||||
nco[0] = (float)co[0] + svec[0];
|
||||
nco[1] = (float)co[1] + svec[1];
|
||||
|
||||
copy_v2_v2(&pt->x, nco);
|
||||
/* apply random to strength */
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_STRENGTH) {
|
||||
if (BLI_frand() > 0.5f) {
|
||||
pt->strength += fac;
|
||||
}
|
||||
else {
|
||||
pt->strength -= fac;
|
||||
}
|
||||
CLAMP_MIN(pt->strength, 0.0f);
|
||||
CLAMP_MAX(pt->strength, 1.0f);
|
||||
}
|
||||
/* apply random to thickness (use pressure) */
|
||||
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) {
|
||||
if (BLI_frand() > 0.5f) {
|
||||
pt->pressure += fac;
|
||||
}
|
||||
else {
|
||||
pt->pressure -= fac;
|
||||
}
|
||||
/* only limit lower value */
|
||||
CLAMP_MIN(pt->pressure, 0.0f);
|
||||
}
|
||||
|
||||
/* done */
|
||||
@@ -1099,7 +1197,9 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
|
||||
/* Apply ----------------------------------------------- */
|
||||
|
||||
/* Apply brush operation to points in this stroke */
|
||||
static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso, bGPDstroke *gps, GP_BrushApplyCb apply)
|
||||
static bool gpsculpt_brush_do_stroke(
|
||||
tGP_BrushEditData *gso, bGPDstroke *gps, bool parented,
|
||||
float diff_mat[4][4], GP_BrushApplyCb apply)
|
||||
{
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
rcti *rect = &gso->brush_rect;
|
||||
@@ -1113,7 +1213,14 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso, bGPDstroke *gps, GP
|
||||
bool changed = false;
|
||||
|
||||
if (gps->totpoints == 1) {
|
||||
gp_point_to_xy(gsc, gps, gps->points, &pc1[0], &pc1[1]);
|
||||
if (!parented) {
|
||||
gp_point_to_xy(gsc, gps, gps->points, &pc1[0], &pc1[1]);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt_temp;
|
||||
gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
|
||||
gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
|
||||
}
|
||||
|
||||
/* do boundbox check first */
|
||||
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
|
||||
@@ -1140,9 +1247,19 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso, bGPDstroke *gps, GP
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!parented) {
|
||||
gp_point_to_xy(gsc, gps, pt1, &pc1[0], &pc1[1]);
|
||||
gp_point_to_xy(gsc, gps, pt2, &pc2[0], &pc2[1]);
|
||||
}
|
||||
else {
|
||||
bGPDspoint npt;
|
||||
gp_point_to_parent_space(pt1, diff_mat, &npt);
|
||||
gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
|
||||
|
||||
gp_point_to_parent_space(pt2, diff_mat, &npt);
|
||||
gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
|
||||
}
|
||||
|
||||
gp_point_to_xy(gsc, gps, pt1, &pc1[0], &pc1[1]);
|
||||
gp_point_to_xy(gsc, gps, pt2, &pc2[0], &pc2[1]);
|
||||
|
||||
/* Check that point segment of the boundbox of the selection stroke */
|
||||
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
|
||||
@@ -1228,72 +1345,101 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
|
||||
|
||||
|
||||
/* Find visible strokes, and perform operations on those if hit */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
float diff_mat[4][4];
|
||||
bool parented = false;
|
||||
|
||||
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
|
||||
{
|
||||
switch (gso->brush_type) {
|
||||
case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_smooth_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_thickness_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
|
||||
{
|
||||
if (gso->first) {
|
||||
/* First time this brush stroke is being applied:
|
||||
* 1) Prepare data buffers (init/clear) for this stroke
|
||||
* 2) Use the points now under the cursor
|
||||
*/
|
||||
gp_brush_grab_stroke_init(gso, gps);
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_grab_store_points);
|
||||
}
|
||||
else {
|
||||
/* Apply effect to the stored points */
|
||||
gp_brush_grab_apply_cached(gso, gps);
|
||||
changed |= true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_PUSH: /* Push points */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_push_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_pinch_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_twist_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_randomize_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type);
|
||||
break;
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
parented = true;
|
||||
}
|
||||
else {
|
||||
parented = false;
|
||||
}
|
||||
|
||||
/* Triangulation must be calculated if changed */
|
||||
if (changed) {
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
gps->tot_triangles = 0;
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDstroke *gps;
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false)
|
||||
continue;
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (gso->brush_type) {
|
||||
case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_smooth_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_thickness_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_STRENGTH: /* Adjust stroke color strength */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_strength_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
|
||||
{
|
||||
if (gso->first) {
|
||||
/* First time this brush stroke is being applied:
|
||||
* 1) Prepare data buffers (init/clear) for this stroke
|
||||
* 2) Use the points now under the cursor
|
||||
*/
|
||||
gp_brush_grab_stroke_init(gso, gps);
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_grab_store_points);
|
||||
}
|
||||
else {
|
||||
/* Apply effect to the stored points */
|
||||
gp_brush_grab_apply_cached(gso, gps, parented, diff_mat);
|
||||
changed |= true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_PUSH: /* Push points */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_push_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_pinch_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_twist_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */
|
||||
{
|
||||
changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_randomize_apply);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type);
|
||||
break;
|
||||
}
|
||||
/* Triangulation must be calculated if changed */
|
||||
if (changed) {
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
gps->tot_triangles = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
@@ -1441,6 +1587,11 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
needs_timer = true;
|
||||
break;
|
||||
|
||||
case GP_EDITBRUSH_TYPE_STRENGTH:
|
||||
brush_rate = 0.01f; // XXX: hardcoded
|
||||
needs_timer = true;
|
||||
break;
|
||||
|
||||
case GP_EDITBRUSH_TYPE_PINCH:
|
||||
brush_rate = 0.001f; // XXX: hardcoded
|
||||
needs_timer = true;
|
||||
|
||||
@@ -142,11 +142,30 @@ static EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C), PointerRN
|
||||
/* convert the coordinates from the given stroke point into 3d-coordinates
|
||||
* - assumes that the active space is the 3D-View
|
||||
*/
|
||||
static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3], rctf *subrect)
|
||||
static void gp_strokepoint_convertcoords(
|
||||
bContext *C, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt,
|
||||
float p3d[3], const rctf *subrect)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
bGPDspoint mypt, *pt;
|
||||
|
||||
float diff_mat[4][4];
|
||||
pt = &mypt;
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent == NULL) {
|
||||
copy_v3_v3(&pt->x, &source_pt->x);
|
||||
}
|
||||
else {
|
||||
/* apply parent transform */
|
||||
float fpt[3];
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
}
|
||||
|
||||
|
||||
if (gps->flag & GP_STROKE_3DSPACE) {
|
||||
/* directly use 3d-coordinates */
|
||||
@@ -628,7 +647,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
bp = &nu->bp[old_nbp - 1];
|
||||
|
||||
/* First point */
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
|
||||
if (prev_bp) {
|
||||
interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC);
|
||||
if (do_gtd) {
|
||||
@@ -649,7 +668,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
/* Second point */
|
||||
/* Note dt2 is always negative, which marks the gap. */
|
||||
if (gps->totpoints > 1) {
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
|
||||
interp_v3_v3v3(p2, p, next_p, -GAP_DFAC);
|
||||
if (do_gtd) {
|
||||
dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
|
||||
@@ -670,9 +689,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
float p[3], next_p[3];
|
||||
float dt = 0.0f;
|
||||
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
|
||||
if (gps->totpoints > 1) {
|
||||
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
|
||||
interp_v3_v3v3(p, p, next_p, -GAP_DFAC);
|
||||
if (do_gtd) {
|
||||
dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
|
||||
@@ -701,10 +720,10 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
|
||||
i++, pt++, bp++)
|
||||
{
|
||||
float p[3];
|
||||
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
|
||||
float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
|
||||
|
||||
/* get coordinates to add at */
|
||||
gp_strokepoint_convertcoords(C, gps, pt, p, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect);
|
||||
|
||||
gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time,
|
||||
width, rad_fac, minmax_weights);
|
||||
@@ -816,12 +835,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
/* get initial coordinates */
|
||||
pt = gps->points;
|
||||
if (tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
|
||||
if (tot > 1) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
|
||||
}
|
||||
if (stitch && tot > 2) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,7 +959,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
|
||||
/* add points */
|
||||
for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) {
|
||||
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
|
||||
float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
|
||||
|
||||
if (i || old_nbezt) {
|
||||
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
|
||||
@@ -964,7 +983,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
|
||||
copy_v3_v3(p3d_cur, p3d_next);
|
||||
|
||||
if (i + 2 < tot) {
|
||||
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
|
||||
gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
|
||||
}
|
||||
|
||||
prev_bezt = bezt;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -125,10 +125,48 @@ static int gp_stroke_edit_poll(bContext *C)
|
||||
return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
|
||||
}
|
||||
|
||||
/* ************ Stroke Hide selection Toggle ************** */
|
||||
|
||||
static int gpencil_hideselect_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
|
||||
if (ts == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* Just toggle alpha... */
|
||||
if (ts->gp_sculpt.alpha > 0.0f) {
|
||||
ts->gp_sculpt.alpha = 0.0f;
|
||||
}
|
||||
else {
|
||||
ts->gp_sculpt.alpha = 1.0f;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Hide Selection";
|
||||
ot->idname = "GPENCIL_OT_selection_opacity_toggle";
|
||||
ot->description = "Hide/Unhide selected points for Grease Pencil strokes setting alpha factor";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = gpencil_hideselect_toggle_exec;
|
||||
ot->poll = gp_stroke_edit_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
|
||||
}
|
||||
|
||||
/* ************** Duplicate Selected Strokes **************** */
|
||||
|
||||
/* Make copies of selected point segments in a selected stroke */
|
||||
static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes)
|
||||
static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, const char *layername)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
@@ -169,6 +207,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes)
|
||||
|
||||
/* make a stupid copy first of the entire stroke (to get the flags too) */
|
||||
gpsd = MEM_dupallocN(gps);
|
||||
strcpy(gpsd->tmp_layerinfo, layername); /* saves original layer name */
|
||||
|
||||
/* initialize triangle memory - will be calculated on next redraw */
|
||||
gpsd->triangles = NULL;
|
||||
@@ -216,8 +255,9 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
|
||||
/* make copies of selected strokes, and deselect these once we're done */
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false)
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
if (gps->totpoints == 1) {
|
||||
@@ -226,6 +266,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* make direct copies of the stroke and its points */
|
||||
gpsd = MEM_dupallocN(gps);
|
||||
strcpy(gpsd->tmp_layerinfo, gpl->info);
|
||||
gpsd->points = MEM_dupallocN(gps->points);
|
||||
|
||||
/* triangle information - will be calculated on next redraw */
|
||||
@@ -238,7 +279,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
else {
|
||||
/* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
|
||||
gp_duplicate_points(gps, &new_strokes);
|
||||
gp_duplicate_points(gps, &new_strokes, gpl->info);
|
||||
}
|
||||
|
||||
/* deselect original stroke, or else the originals get moved too
|
||||
@@ -345,6 +386,7 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* make direct copies of the stroke and its points */
|
||||
gpsd = MEM_dupallocN(gps);
|
||||
strcpy(gpsd->tmp_layerinfo, gpl->info); /* saves original layer name */
|
||||
gpsd->points = MEM_dupallocN(gps->points);
|
||||
|
||||
/* triangles cache - will be recalculated on next redraw */
|
||||
@@ -358,7 +400,7 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
else {
|
||||
/* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
|
||||
gp_duplicate_points(gps, &gp_strokes_copypastebuf);
|
||||
gp_duplicate_points(gps, &gp_strokes_copypastebuf, gpl->info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,13 +437,20 @@ static int gp_strokes_paste_poll(bContext *C)
|
||||
return (CTX_data_active_gpencil_layer(C) != NULL) && (!BLI_listbase_is_empty(&gp_strokes_copypastebuf));
|
||||
}
|
||||
|
||||
enum {
|
||||
GP_COPY_ONLY = -1,
|
||||
GP_COPY_MERGE = 1
|
||||
};
|
||||
|
||||
static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
|
||||
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */
|
||||
bGPDframe *gpf;
|
||||
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
|
||||
/* check for various error conditions */
|
||||
if (gpd == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
|
||||
@@ -415,7 +464,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
|
||||
/* no active layer - let's just create one */
|
||||
gpl = gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true);
|
||||
}
|
||||
else if (gpencil_layer_is_editable(gpl) == false) {
|
||||
else if ((gpencil_layer_is_editable(gpl) == false) && (type == GP_COPY_MERGE)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can not paste strokes when active layer is hidden or locked");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
@@ -463,26 +512,34 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
|
||||
* we are obliged to add a new frame if one
|
||||
* doesn't exist already
|
||||
*/
|
||||
gpf = gpencil_layer_getframe(gpl, CFRA, true);
|
||||
|
||||
if (gpf) {
|
||||
bGPDstroke *gps;
|
||||
|
||||
/* Copy each stroke into the layer */
|
||||
for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
|
||||
if (ED_gpencil_stroke_can_use(C, gps)) {
|
||||
bGPDstroke *new_stroke = MEM_dupallocN(gps);
|
||||
/* need to verify if layer exist nad frame */
|
||||
if (type != GP_COPY_MERGE) {
|
||||
gpl = BLI_findstring(&gpd->layers, gps->tmp_layerinfo, offsetof(bGPDlayer, info));
|
||||
if (gpl == NULL) {
|
||||
/* no layer - use active (only if layer deleted before paste) */
|
||||
gpl = CTX_data_active_gpencil_layer(C);
|
||||
}
|
||||
}
|
||||
gpf = gpencil_layer_getframe(gpl, CFRA, true);
|
||||
if (gpf) {
|
||||
bGPDstroke *new_stroke = MEM_dupallocN(gps);
|
||||
new_stroke->tmp_layerinfo[0] = '\0';
|
||||
|
||||
new_stroke->points = MEM_dupallocN(gps->points);
|
||||
new_stroke->points = MEM_dupallocN(gps->points);
|
||||
|
||||
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
|
||||
new_stroke->triangles = NULL;
|
||||
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
|
||||
new_stroke->triangles = NULL;
|
||||
|
||||
new_stroke->next = new_stroke->prev = NULL;
|
||||
BLI_addtail(&gpf->strokes, new_stroke);
|
||||
new_stroke->next = new_stroke->prev = NULL;
|
||||
BLI_addtail(&gpf->strokes, new_stroke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* updates */
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
@@ -492,10 +549,16 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
|
||||
|
||||
void GPENCIL_OT_paste(wmOperatorType *ot)
|
||||
{
|
||||
static EnumPropertyItem copy_type[] = {
|
||||
{GP_COPY_ONLY, "COPY", 0, "Copy", ""},
|
||||
{GP_COPY_MERGE, "MERGE", 0, "Merge", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Paste Strokes";
|
||||
ot->idname = "GPENCIL_OT_paste";
|
||||
ot->description = "Paste previously copied strokes into active layer";
|
||||
ot->description = "Paste previously copied strokes or copy and merge in active layer";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = gp_strokes_paste_exec;
|
||||
@@ -503,6 +566,8 @@ void GPENCIL_OT_paste(wmOperatorType *ot)
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
ot->prop = RNA_def_enum(ot->srna, "type", copy_type, 0, "Type", "");
|
||||
}
|
||||
|
||||
/* ******************* Move To Layer ****************************** */
|
||||
@@ -1069,7 +1134,7 @@ void GPENCIL_OT_delete(wmOperatorType *ot)
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Delete...";
|
||||
ot->name = "Delete";
|
||||
ot->idname = "GPENCIL_OT_delete";
|
||||
ot->description = "Delete selected Grease Pencil strokes, vertices, or frames";
|
||||
|
||||
@@ -1124,25 +1189,65 @@ static int gp_snap_poll(bContext *C)
|
||||
static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
RegionView3D *rv3d = CTX_wm_region_data(C);
|
||||
float gridf = rv3d->gridview;
|
||||
const float gridf = rv3d->gridview;
|
||||
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
float diff_mat[4][4];
|
||||
|
||||
// TOOD: if entire stroke is selected, offset entire stroke by same amount?
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* only editable and visible layers are considered */
|
||||
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
}
|
||||
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDstroke *gps;
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false)
|
||||
continue;
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
// TOOD: if entire stroke is selected, offset entire stroke by same amount?
|
||||
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
|
||||
/* only if point is selected.. */
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
if (gpl->parent == NULL) {
|
||||
pt->x = gridf * floorf(0.5f + pt->x / gridf);
|
||||
pt->y = gridf * floorf(0.5f + pt->y / gridf);
|
||||
pt->z = gridf * floorf(0.5f + pt->z / gridf);
|
||||
}
|
||||
else {
|
||||
/* apply parent transformations */
|
||||
float fpt[3];
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
|
||||
fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf);
|
||||
fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf);
|
||||
fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf);
|
||||
|
||||
/* return data */
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
gp_apply_parent_point(gpl, pt);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
/* only if point is selected.. */
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
pt->x = gridf * floorf(0.5f + pt->x / gridf);
|
||||
pt->y = gridf * floorf(0.5f + pt->y / gridf);
|
||||
pt->z = gridf * floorf(0.5f + pt->z / gridf);
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -1173,37 +1278,64 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
|
||||
const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
|
||||
const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d);
|
||||
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
float diff_mat[4][4];
|
||||
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
if ((gps->flag & GP_STROKE_SELECT) == 0)
|
||||
continue;
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* only editable and visible layers are considered */
|
||||
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
if (use_offset) {
|
||||
float offset[3];
|
||||
|
||||
/* compute offset from first point of stroke to cursor */
|
||||
/* TODO: Allow using midpoint instead? */
|
||||
sub_v3_v3v3(offset, cursor_global, &gps->points->x);
|
||||
|
||||
/* apply offset to all points in the stroke */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
add_v3_v3(&pt->x, offset);
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* affect each selected point */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
copy_v3_v3(&pt->x, cursor_global);
|
||||
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDstroke *gps;
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false)
|
||||
continue;
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
if ((gps->flag & GP_STROKE_SELECT) == 0)
|
||||
continue;
|
||||
|
||||
if (use_offset) {
|
||||
float offset[3];
|
||||
|
||||
/* compute offset from first point of stroke to cursor */
|
||||
/* TODO: Allow using midpoint instead? */
|
||||
sub_v3_v3v3(offset, cursor_global, &gps->points->x);
|
||||
|
||||
/* apply offset to all points in the stroke */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
add_v3_v3(&pt->x, offset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* affect each selected point */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
copy_v3_v3(&pt->x, cursor_global);
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent_point(gpl, pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -1243,24 +1375,57 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
/* calculate midpoints from selected points */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
float diff_mat[4][4];
|
||||
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
if ((gps->flag & GP_STROKE_SELECT) == 0)
|
||||
continue;
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* only editable and visible layers are considered */
|
||||
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
}
|
||||
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDstroke *gps;
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false)
|
||||
continue;
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
|
||||
if ((gps->flag & GP_STROKE_SELECT) == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
if (gpl->parent == NULL) {
|
||||
add_v3_v3(centroid, &pt->x);
|
||||
minmax_v3v3_v3(min, max, &pt->x);
|
||||
}
|
||||
else {
|
||||
/* apply parent transformations */
|
||||
float fpt[3];
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
|
||||
add_v3_v3(centroid, fpt);
|
||||
minmax_v3v3_v3(min, max, fpt);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
add_v3_v3(centroid, &pt->x);
|
||||
minmax_v3v3_v3(min, max, &pt->x);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
if (v3d->around == V3D_AROUND_CENTER_MEAN && count) {
|
||||
mul_v3_fl(centroid, 1.0f / (float)count);
|
||||
|
||||
@@ -100,6 +100,23 @@ void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
|
||||
void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt,
|
||||
int *r_x, int *r_y);
|
||||
|
||||
/**
|
||||
* Convert point to parent space
|
||||
*
|
||||
* \param pt Original point
|
||||
* \param diff_mat Matrix with the difference between original parent matrix
|
||||
* \param[out] r_pt Pointer to new point after apply matrix
|
||||
*/
|
||||
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt);
|
||||
/**
|
||||
* Change points position relative to parent object
|
||||
*/
|
||||
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps);
|
||||
/**
|
||||
* Change point position relative to parent object
|
||||
*/
|
||||
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt);
|
||||
|
||||
/**
|
||||
* Convert a screenspace point to a 3D Grease Pencil coordinate.
|
||||
*
|
||||
@@ -116,6 +133,10 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float
|
||||
|
||||
int gp_add_poll(struct bContext *C);
|
||||
int gp_active_layer_poll(struct bContext *C);
|
||||
int gp_active_brush_poll(struct bContext *C);
|
||||
int gp_active_palette_poll(struct bContext *C);
|
||||
int gp_active_palettecolor_poll(struct bContext *C);
|
||||
int gp_brush_crt_presets_poll(bContext *C);
|
||||
|
||||
/* Copy/Paste Buffer --------------------------------- */
|
||||
/* gpencil_edit.c */
|
||||
@@ -136,6 +157,22 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
|
||||
*/
|
||||
bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
|
||||
|
||||
/**
|
||||
* Apply smooth for strength to stroke point
|
||||
* \param gps Stroke to smooth
|
||||
* \param i Point index
|
||||
* \param inf Amount of smoothing to apply
|
||||
*/
|
||||
bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf);
|
||||
|
||||
/**
|
||||
* Apply smooth for thickness to stroke point (use pressure)
|
||||
* \param gps Stroke to smooth
|
||||
* \param i Point index
|
||||
* \param inf Amount of smoothing to apply
|
||||
*/
|
||||
bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf);
|
||||
|
||||
/**
|
||||
* Subdivide a stroke once, by adding points at the midpoint between each pair of points
|
||||
* \param gps Stroke data
|
||||
@@ -143,11 +180,25 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
|
||||
*/
|
||||
void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints);
|
||||
|
||||
/**
|
||||
* Add randomness to stroke
|
||||
* \param gps Stroke data
|
||||
* \param brsuh Brush data
|
||||
*/
|
||||
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush);
|
||||
|
||||
/* Layers Enums -------------------------------------- */
|
||||
|
||||
struct EnumPropertyItem *ED_gpencil_layers_enum_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free);
|
||||
struct EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free);
|
||||
|
||||
/* Enums of GP Brushes */
|
||||
EnumPropertyItem *ED_gpencil_brushes_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
|
||||
bool *r_free);
|
||||
|
||||
/* Enums of GP palettes */
|
||||
EnumPropertyItem *ED_gpencil_palettes_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
|
||||
bool *r_free);
|
||||
/* ***************************************************** */
|
||||
/* Operator Defines */
|
||||
|
||||
@@ -166,6 +217,7 @@ typedef enum eGPencil_PaintModes {
|
||||
/* stroke editing ----- */
|
||||
|
||||
void GPENCIL_OT_editmode_toggle(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_selection_opacity_toggle(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_select(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_select_all(struct wmOperatorType *ot);
|
||||
@@ -216,12 +268,45 @@ void GPENCIL_OT_lock_all(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_unlock_all(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_layer_isolate(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_layer_merge(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_convert(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_stroke_arrange(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_change_color(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_lock_color(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_apply_thickness(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_cyclical_set(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_join(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_stroke_flip(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_brush_add(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_remove(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_change(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_move(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_presets_create(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_copy(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_brush_select(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_palette_add(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palette_remove(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palette_change(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palette_lock_layer(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_add(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_remove(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_isolate(struct wmOperatorType *ot);
|
||||
|
||||
void GPENCIL_OT_palettecolor_hide(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_reveal(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_lock_all(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_unlock_all(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_move(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_select(struct wmOperatorType *ot);
|
||||
void GPENCIL_OT_palettecolor_copy(struct wmOperatorType *ot);
|
||||
|
||||
/* undo stack ---------- */
|
||||
|
||||
void gpencil_undo_init(struct bGPdata *gpd);
|
||||
@@ -273,4 +358,39 @@ typedef enum ACTCONT_TYPES {
|
||||
ACTCONT_GPENCIL
|
||||
} ACTCONT_TYPES;
|
||||
|
||||
/**
|
||||
* Iterate over all editable strokes in the current context,
|
||||
* stopping on each usable layer + stroke pair (i.e. gpl and gps)
|
||||
* to perform some operations on the stroke.
|
||||
*
|
||||
* \param gpl The identifier to use for the layer of the stroke being processed.
|
||||
* Choose a suitable value to avoid name clashes.
|
||||
* \param gps The identifier to use for current stroke being processed.
|
||||
* Choose a suitable value to avoid name clashes.
|
||||
*/
|
||||
#define GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) \
|
||||
{ \
|
||||
CTX_DATA_BEGIN(C, bGPDlayer*, gpl, editable_gpencil_layers) \
|
||||
{ \
|
||||
if (gpl->actframe == NULL) \
|
||||
continue; \
|
||||
/* calculate difference matrix if parent object */ \
|
||||
float diff_mat[4][4]; \
|
||||
ED_gpencil_parent_location(gpl, diff_mat); \
|
||||
/* loop over strokes */ \
|
||||
for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { \
|
||||
/* skip strokes that are invalid for current view */ \
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) \
|
||||
continue; \
|
||||
/* check if the color is editable */ \
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) \
|
||||
continue; \
|
||||
/* ... Do Stuff With Strokes ... */
|
||||
|
||||
#define GP_EDITABLE_STROKES_END \
|
||||
} \
|
||||
} \
|
||||
CTX_DATA_END; \
|
||||
} (void)0
|
||||
|
||||
#endif /* __GPENCIL_INTERN_H__ */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -140,8 +140,8 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
|
||||
* that the only data being edited is that of the Grease Pencil strokes
|
||||
*/
|
||||
|
||||
/* FKEY = Eraser Radius */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
|
||||
/* CTRL + FKEY = Eraser Radius */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius");
|
||||
|
||||
|
||||
@@ -169,8 +169,8 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength");
|
||||
|
||||
/* Ctrl-FKEY = Sculpt Brush Size */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
|
||||
/* FKEY = Sculpt Brush Size */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size");
|
||||
|
||||
|
||||
@@ -267,12 +267,35 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "unselected", true);
|
||||
|
||||
WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
/* Isolate Layer */
|
||||
WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* Move to Layer */
|
||||
WM_keymap_add_item(keymap, "GPENCIL_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* Select drawing brush using index */
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", ONEKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 0);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", TWOKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 1);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", THREEKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 2);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", FOURKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 3);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", FIVEKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 4);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", SIXKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 5);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", SEVENKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 6);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", EIGHTKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 7);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", NINEKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 8);
|
||||
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", ZEROKEY, KM_PRESS, 0, 0);
|
||||
RNA_int_set(kmi->ptr, "index", 9);
|
||||
|
||||
/* Transform Tools */
|
||||
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
|
||||
@@ -318,6 +341,7 @@ void ED_operatortypes_gpencil(void)
|
||||
/* Editing (Strokes) ------------ */
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_editmode_toggle);
|
||||
WM_operatortype_append(GPENCIL_OT_selection_opacity_toggle);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_select);
|
||||
WM_operatortype_append(GPENCIL_OT_select_all);
|
||||
@@ -362,12 +386,44 @@ void ED_operatortypes_gpencil(void)
|
||||
WM_operatortype_append(GPENCIL_OT_lock_all);
|
||||
WM_operatortype_append(GPENCIL_OT_unlock_all);
|
||||
WM_operatortype_append(GPENCIL_OT_layer_isolate);
|
||||
WM_operatortype_append(GPENCIL_OT_layer_merge);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_active_frame_delete);
|
||||
WM_operatortype_append(GPENCIL_OT_active_frames_delete_all);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_convert);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_arrange);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_change_color);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_lock_color);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_apply_thickness);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_cyclical_set);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_join);
|
||||
WM_operatortype_append(GPENCIL_OT_stroke_flip);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_palette_add);
|
||||
WM_operatortype_append(GPENCIL_OT_palette_remove);
|
||||
WM_operatortype_append(GPENCIL_OT_palette_change);
|
||||
WM_operatortype_append(GPENCIL_OT_palette_lock_layer);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_add);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_remove);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_isolate);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_hide);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_reveal);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_lock_all);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_unlock_all);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_move);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_select);
|
||||
WM_operatortype_append(GPENCIL_OT_palettecolor_copy);
|
||||
|
||||
WM_operatortype_append(GPENCIL_OT_brush_add);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_remove);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_change);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_move);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_presets_create);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_copy);
|
||||
WM_operatortype_append(GPENCIL_OT_brush_select);
|
||||
|
||||
/* Editing (Time) --------------- */
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -39,21 +39,26 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_tracking.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "UI_view2d.h"
|
||||
@@ -151,6 +156,10 @@ typedef struct tGPsdata {
|
||||
float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
|
||||
|
||||
void *erasercursor; /* radial cursor data for drawing eraser */
|
||||
|
||||
bGPDpalettecolor *palettecolor; /* current palette color */
|
||||
bGPDbrush *brush; /* current drawing brush */
|
||||
short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */
|
||||
} tGPsdata;
|
||||
|
||||
/* ------ */
|
||||
@@ -333,10 +342,90 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
|
||||
}
|
||||
}
|
||||
|
||||
/* apply jitter to stroke */
|
||||
static void gp_brush_jitter(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2], int r_mval[2])
|
||||
{
|
||||
float pressure = pt->pressure;
|
||||
float tmp_pressure = pt->pressure;
|
||||
if (brush->draw_jitter > 0.0f) {
|
||||
float curvef = curvemapping_evaluateF(brush->cur_jitter, 0, pressure);
|
||||
tmp_pressure = curvef * brush->draw_sensitivity;
|
||||
}
|
||||
const float exfactor = (brush->draw_jitter + 2.0f) * (brush->draw_jitter + 2.0f); /* exponential value */
|
||||
const float fac = BLI_frand() * exfactor * tmp_pressure;
|
||||
/* Jitter is applied perpendicular to the mouse movement vector (2D space) */
|
||||
float mvec[2], svec[2];
|
||||
/* mouse movement in ints -> floats */
|
||||
if (gpd->sbuffer_size > 1) {
|
||||
mvec[0] = (float)(mval[0] - (pt - 1)->x);
|
||||
mvec[1] = (float)(mval[1] - (pt - 1)->y);
|
||||
normalize_v2(mvec);
|
||||
}
|
||||
else {
|
||||
mvec[0] = 0.0f;
|
||||
mvec[1] = 0.0f;
|
||||
}
|
||||
/* rotate mvec by 90 degrees... */
|
||||
svec[0] = -mvec[1];
|
||||
svec[1] = mvec[0];
|
||||
/* scale the displacement by the random, and apply */
|
||||
if (BLI_frand() > 0.5f) {
|
||||
mul_v2_fl(svec, -fac);
|
||||
}
|
||||
else {
|
||||
mul_v2_fl(svec, fac);
|
||||
}
|
||||
|
||||
r_mval[0] = mval[0] + svec[0];
|
||||
r_mval[1] = mval[1] + svec[1];
|
||||
|
||||
}
|
||||
|
||||
/* apply pressure change depending of the angle of the stroke to simulate a pen with shape */
|
||||
static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2])
|
||||
{
|
||||
float mvec[2];
|
||||
float sen = brush->draw_angle_factor; /* sensitivity */;
|
||||
float fac;
|
||||
float mpressure;
|
||||
|
||||
float angle = brush->draw_angle; /* default angle of brush in radians */;
|
||||
float v0[2] = { cos(angle), sin(angle) }; /* angle vector of the brush with full thickness */
|
||||
|
||||
/* Apply to first point (only if there are 2 points because before no data to do it ) */
|
||||
if (gpd->sbuffer_size == 1) {
|
||||
mvec[0] = (float)(mval[0] - (pt - 1)->x);
|
||||
mvec[1] = (float)(mval[1] - (pt - 1)->y);
|
||||
normalize_v2(mvec);
|
||||
|
||||
/* uses > 1.0f to get a smooth transition in first point */
|
||||
fac = 1.4f - fabs(dot_v2v2(v0, mvec)); /* 0.0 to 1.0 */
|
||||
(pt - 1)->pressure = (pt - 1)->pressure - (sen * fac);
|
||||
|
||||
CLAMP((pt - 1)->pressure, GPENCIL_ALPHA_OPACITY_THRESH, 1.0f);
|
||||
}
|
||||
|
||||
/* apply from second point */
|
||||
if (gpd->sbuffer_size >= 1) {
|
||||
mvec[0] = (float)(mval[0] - (pt - 1)->x);
|
||||
mvec[1] = (float)(mval[1] - (pt - 1)->y);
|
||||
normalize_v2(mvec);
|
||||
|
||||
fac = 1.0f - fabs(dot_v2v2(v0, mvec)); /* 0.0 to 1.0 */
|
||||
/* interpolate with previous point for smoother transitions */
|
||||
mpressure = interpf(pt->pressure - (sen * fac), (pt - 1)->pressure, 0.3f);
|
||||
pt->pressure = mpressure;
|
||||
|
||||
CLAMP(pt->pressure, GPENCIL_ALPHA_OPACITY_THRESH, 1.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* add current stroke-point to buffer (returns whether point was successfully added) */
|
||||
static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, double curtime)
|
||||
{
|
||||
bGPdata *gpd = p->gpd;
|
||||
bGPDbrush *brush = p->brush;
|
||||
tGPspoint *pt;
|
||||
|
||||
/* check painting mode */
|
||||
@@ -349,6 +438,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
|
||||
/* store settings */
|
||||
copy_v2_v2_int(&pt->x, mval);
|
||||
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
|
||||
pt->strength = 1.0f;
|
||||
pt->time = (float)(curtime - p->inittime);
|
||||
|
||||
/* increment buffer size */
|
||||
@@ -363,6 +453,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
|
||||
/* store settings */
|
||||
copy_v2_v2_int(&pt->x, mval);
|
||||
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
|
||||
pt->strength = 1.0f;
|
||||
pt->time = (float)(curtime - p->inittime);
|
||||
|
||||
/* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
|
||||
@@ -381,8 +472,65 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
|
||||
pt = ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
|
||||
|
||||
/* store settings */
|
||||
copy_v2_v2_int(&pt->x, mval);
|
||||
pt->pressure = pressure;
|
||||
/* pressure */
|
||||
if (brush->flag & GP_BRUSH_USE_PRESSURE) {
|
||||
float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure);
|
||||
pt->pressure = curvef * brush->draw_sensitivity;
|
||||
}
|
||||
else {
|
||||
pt->pressure = 1.0f;
|
||||
}
|
||||
/* Apply jitter to position */
|
||||
if (brush->draw_jitter > 0.0f) {
|
||||
int r_mval[2];
|
||||
gp_brush_jitter(gpd, brush, pt, mval, r_mval);
|
||||
copy_v2_v2_int(&pt->x, r_mval);
|
||||
}
|
||||
else {
|
||||
copy_v2_v2_int(&pt->x, mval);
|
||||
}
|
||||
/* apply randomness to pressure */
|
||||
if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_PRESSURE)) {
|
||||
float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure);
|
||||
float tmp_pressure = curvef * brush->draw_sensitivity;
|
||||
if (BLI_frand() > 0.5f) {
|
||||
pt->pressure -= tmp_pressure * brush->draw_random_press * BLI_frand();
|
||||
}
|
||||
else {
|
||||
pt->pressure += tmp_pressure * brush->draw_random_press * BLI_frand();
|
||||
}
|
||||
CLAMP(pt->pressure, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
}
|
||||
|
||||
/* apply angle of stroke to brush size */
|
||||
if (brush->draw_angle_factor > 0.0f) {
|
||||
gp_brush_angle(gpd, brush, pt, mval);
|
||||
}
|
||||
|
||||
/* color strength */
|
||||
if (brush->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
|
||||
float curvef = curvemapping_evaluateF(brush->cur_strength, 0, pressure);
|
||||
float tmp_pressure = curvef * brush->draw_sensitivity;
|
||||
|
||||
pt->strength = tmp_pressure * brush->draw_strength;
|
||||
}
|
||||
else {
|
||||
pt->strength = brush->draw_strength;
|
||||
}
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
|
||||
/* apply randomness to color strength */
|
||||
if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_STRENGTH)) {
|
||||
if (BLI_frand() > 0.5f) {
|
||||
pt->strength -= pt->strength * brush->draw_random_press * BLI_frand();
|
||||
}
|
||||
else {
|
||||
pt->strength += pt->strength * brush->draw_random_press * BLI_frand();
|
||||
}
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
}
|
||||
|
||||
/* point time */
|
||||
pt->time = (float)(curtime - p->inittime);
|
||||
|
||||
/* increment counters */
|
||||
@@ -395,12 +543,15 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
|
||||
return GP_STROKEADD_NORMAL;
|
||||
}
|
||||
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
|
||||
|
||||
bGPDlayer *gpl = gpencil_layer_getactive(gpd);
|
||||
/* get pointer to destination point */
|
||||
pt = (tGPspoint *)(gpd->sbuffer);
|
||||
|
||||
/* store settings */
|
||||
copy_v2_v2_int(&pt->x, mval);
|
||||
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
|
||||
pt->strength = 1.0f;
|
||||
pt->time = (float)(curtime - p->inittime);
|
||||
|
||||
/* if there's stroke for this poly line session add (or replace last) point
|
||||
@@ -433,10 +584,16 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent_point(gpl, pts);
|
||||
}
|
||||
/* copy pressure and time */
|
||||
pts->pressure = pt->pressure;
|
||||
pts->strength = pt->strength;
|
||||
pts->time = pt->time;
|
||||
/* force fill recalc */
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
}
|
||||
|
||||
/* increment counters */
|
||||
@@ -534,6 +691,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
bGPDstroke *gps;
|
||||
bGPDspoint *pt;
|
||||
tGPspoint *ptc;
|
||||
bGPDbrush *brush = p->brush;
|
||||
|
||||
int i, totelem;
|
||||
/* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
|
||||
@@ -569,7 +727,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* copy appropriate settings for stroke */
|
||||
gps->totpoints = totelem;
|
||||
gps->thickness = p->gpl->thickness;
|
||||
gps->thickness = brush->thickness;
|
||||
gps->flag = gpd->sbuffer_sflag;
|
||||
gps->inittime = p->inittime;
|
||||
|
||||
@@ -577,7 +735,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
|
||||
/* allocate enough memory for a continuous array for storage points */
|
||||
int sublevel = gpl->sublevel;
|
||||
int sublevel = brush->sublevel;
|
||||
int new_totpoints = gps->totpoints;
|
||||
|
||||
for (i = 0; i < sublevel; i++) {
|
||||
@@ -600,9 +758,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent_point(gpl, pt);
|
||||
}
|
||||
/* copy pressure and time */
|
||||
pt->pressure = ptc->pressure;
|
||||
pt->strength = ptc->strength;
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
pt->time = ptc->time;
|
||||
|
||||
pt++;
|
||||
@@ -614,9 +777,15 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
|
||||
/* if parented change position relative to parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent_point(gpl, pt);
|
||||
}
|
||||
|
||||
/* copy pressure and time */
|
||||
pt->pressure = ptc->pressure;
|
||||
pt->strength = ptc->strength;
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
pt->time = ptc->time;
|
||||
}
|
||||
}
|
||||
@@ -626,9 +795,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* convert screen-coordinates to appropriate coordinates (and store them) */
|
||||
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent_point(gpl, pt);
|
||||
}
|
||||
/* copy pressure and time */
|
||||
pt->pressure = ptc->pressure;
|
||||
pt->strength = ptc->strength;
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
pt->time = ptc->time;
|
||||
}
|
||||
else {
|
||||
@@ -703,6 +877,8 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
|
||||
/* copy pressure and time */
|
||||
pt->pressure = ptc->pressure;
|
||||
pt->strength = ptc->strength;
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
pt->time = ptc->time;
|
||||
}
|
||||
|
||||
@@ -716,25 +892,38 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
|
||||
gp_subdivide_stroke(gps, totpoints);
|
||||
}
|
||||
}
|
||||
/* apply randomness to stroke */
|
||||
if (brush->draw_random_sub > 0.0f) {
|
||||
gp_randomize_stroke(gps, brush);
|
||||
}
|
||||
|
||||
/* smooth stroke after subdiv - only if there's something to do
|
||||
* for each iteration, the factor is reduced to get a better smoothing without changing too much
|
||||
* the original stroke
|
||||
*/
|
||||
if (gpl->draw_smoothfac > 0.0f) {
|
||||
if (brush->draw_smoothfac > 0.0f) {
|
||||
float reduce = 0.0f;
|
||||
for (int r = 0; r < gpl->draw_smoothlvl; ++r) {
|
||||
for (int r = 0; r < brush->draw_smoothlvl; ++r) {
|
||||
for (i = 0; i < gps->totpoints; i++) {
|
||||
/* NOTE: No pressure smoothing, or else we get annoying thickness changes while drawing... */
|
||||
gp_smooth_stroke(gps, i, gpl->draw_smoothfac - reduce, false);
|
||||
gp_smooth_stroke(gps, i, brush->draw_smoothfac - reduce, false);
|
||||
}
|
||||
reduce += 0.25f; // reduce the factor
|
||||
}
|
||||
}
|
||||
/* if parented change position relative to parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
gp_apply_parent(gpl, gps);
|
||||
}
|
||||
|
||||
if (depth_arr)
|
||||
MEM_freeN(depth_arr);
|
||||
}
|
||||
/* Save palette color */
|
||||
bGPDpalette *palette = gpencil_palette_getactive(p->gpd);
|
||||
bGPDpalettecolor *palcolor = gpencil_palettecolor_getactive(palette);
|
||||
gps->palcolor = palcolor;
|
||||
strcpy(gps->colorname, palcolor->info);
|
||||
|
||||
/* add stroke to frame */
|
||||
BLI_addtail(&p->gpf->strokes, gps);
|
||||
@@ -761,12 +950,21 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons
|
||||
(p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH))
|
||||
{
|
||||
RegionView3D *rv3d = p->ar->regiondata;
|
||||
bGPDlayer *gpl = p->gpl;
|
||||
|
||||
const int mval[2] = {x, y};
|
||||
float mval_3d[3];
|
||||
float fpt[3];
|
||||
|
||||
float diff_mat[4][4];
|
||||
/* calculate difference matrix if parent object */
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
|
||||
if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) {
|
||||
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
|
||||
const float depth_pt = view3d_point_depth(rv3d, &pt->x);
|
||||
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
const float depth_pt = view3d_point_depth(rv3d, fpt);
|
||||
|
||||
if (depth_pt > depth_mval) {
|
||||
return true;
|
||||
@@ -804,6 +1002,12 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
int pc1[2] = {0};
|
||||
int pc2[2] = {0};
|
||||
int i;
|
||||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
}
|
||||
|
||||
if (gps->totpoints == 0) {
|
||||
/* just free stroke */
|
||||
@@ -816,8 +1020,14 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
else if (gps->totpoints == 1) {
|
||||
/* only process if it hasn't been masked out... */
|
||||
if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) {
|
||||
gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
|
||||
|
||||
if (gpl->parent == NULL) {
|
||||
gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt_temp;
|
||||
gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
|
||||
gp_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
|
||||
}
|
||||
/* do boundbox check first */
|
||||
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
|
||||
/* only check if point is inside */
|
||||
@@ -826,7 +1036,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
// XXX: pressure sensitive eraser should apply here too?
|
||||
MEM_freeN(gps->points);
|
||||
if (gps->triangles)
|
||||
MEM_freeN(gps->triangles);
|
||||
MEM_freeN(gps->triangles);
|
||||
BLI_freelinkN(&gpf->strokes, gps);
|
||||
}
|
||||
}
|
||||
@@ -836,7 +1046,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
/* Pressure threshold at which stroke should be culled: Calculated as pressure value
|
||||
* below which we would have invisible strokes
|
||||
*/
|
||||
const float cull_thresh = (gpl->thickness) ? 1.0f / ((float)gpl->thickness) : 1.0f;
|
||||
const float cull_thresh = (gps->thickness) ? 1.0f / ((float)gps->thickness) : 1.0f;
|
||||
|
||||
/* Amount to decrease the pressure of each point with each stroke */
|
||||
// TODO: Fetch from toolsettings, or compute based on thickness instead?
|
||||
@@ -870,9 +1080,18 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
|
||||
if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT))
|
||||
continue;
|
||||
|
||||
/* get coordinates of point in screenspace */
|
||||
gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
|
||||
gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
|
||||
if (gpl->parent == NULL) {
|
||||
gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
|
||||
gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
|
||||
}
|
||||
else {
|
||||
bGPDspoint npt;
|
||||
gp_point_to_parent_space(pt1, diff_mat, &npt);
|
||||
gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
|
||||
|
||||
gp_point_to_parent_space(pt2, diff_mat, &npt);
|
||||
gp_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]);
|
||||
}
|
||||
|
||||
/* Check that point segment of the boundbox of the eraser stroke */
|
||||
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
|
||||
@@ -955,7 +1174,10 @@ static void gp_stroke_doeraser(tGPsdata *p)
|
||||
/* loop over strokes, checking segments for intersections */
|
||||
for (gps = gpf->strokes.first; gps; gps = gpn) {
|
||||
gpn = gps->next;
|
||||
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Not all strokes in the datablock may be valid in the current editor/context
|
||||
* (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
|
||||
*/
|
||||
@@ -994,6 +1216,78 @@ static void gp_session_validatebuffer(tGPsdata *p)
|
||||
p->inittime = 0.0;
|
||||
}
|
||||
|
||||
/* create a new palette color */
|
||||
static bGPDpalettecolor *gp_create_new_color(bGPDpalette *palette)
|
||||
{
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
palcolor = gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
|
||||
|
||||
return palcolor;
|
||||
}
|
||||
|
||||
/* initialize a drawing brush */
|
||||
static void gp_init_drawing_brush(ToolSettings *ts, tGPsdata *p)
|
||||
{
|
||||
bGPDbrush *brush;
|
||||
|
||||
/* if not exist, create a new one */
|
||||
if (BLI_listbase_is_empty(&ts->gp_brushes)) {
|
||||
/* create new brushes */
|
||||
gpencil_brush_init_presets(ts);
|
||||
brush = gpencil_brush_getactive(ts);
|
||||
}
|
||||
else {
|
||||
/* Use the current */
|
||||
brush = gpencil_brush_getactive(ts);
|
||||
}
|
||||
/* be sure curves are initializated */
|
||||
curvemapping_initialize(brush->cur_sensitivity);
|
||||
curvemapping_initialize(brush->cur_strength);
|
||||
curvemapping_initialize(brush->cur_jitter);
|
||||
|
||||
/* asign to temp tGPsdata */
|
||||
p->brush = brush;
|
||||
}
|
||||
|
||||
|
||||
/* initialize a paint palette brush and a default color if not exist */
|
||||
static void gp_init_palette(tGPsdata *p)
|
||||
{
|
||||
bGPdata *gpd;
|
||||
bGPDpalette *palette;
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
gpd = p->gpd;
|
||||
|
||||
/* if not exist, create a new palette */
|
||||
if (BLI_listbase_is_empty(&gpd->palettes)) {
|
||||
/* create new palette */
|
||||
palette = gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true);
|
||||
/* now create a default color */
|
||||
palcolor = gp_create_new_color(palette);
|
||||
}
|
||||
else {
|
||||
/* Use the current palette and color */
|
||||
palette = gpencil_palette_getactive(gpd);
|
||||
/* the palette needs one color */
|
||||
if (BLI_listbase_is_empty(&palette->colors)) {
|
||||
palcolor = gp_create_new_color(palette);
|
||||
}
|
||||
else {
|
||||
palcolor = gpencil_palettecolor_getactive(palette);
|
||||
}
|
||||
/* in some situations can be null, so use first */
|
||||
if (palcolor == NULL) {
|
||||
gpencil_palettecolor_setactive(palette, palette->colors.first);
|
||||
palcolor = palette->colors.first;
|
||||
}
|
||||
}
|
||||
|
||||
/* asign to temp tGPsdata */
|
||||
p->palettecolor = palcolor;
|
||||
}
|
||||
|
||||
/* (re)init new painting data */
|
||||
static bool gp_session_initdata(bContext *C, tGPsdata *p)
|
||||
{
|
||||
@@ -1158,6 +1452,15 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
|
||||
|
||||
/* clear out buffer (stored in gp-data), in case something contaminated it */
|
||||
gp_session_validatebuffer(p);
|
||||
/* set brush and create a new one if null */
|
||||
gp_init_drawing_brush(ts, p);
|
||||
/* set palette info and create a new one if null */
|
||||
gp_init_palette(p);
|
||||
/* set palette colors */
|
||||
bGPDpalettecolor *palcolor = p->palettecolor;
|
||||
bGPdata *pdata = p->gpd;
|
||||
copy_v4_v4(pdata->scolor, palcolor->color);
|
||||
pdata->sflag = palcolor->flag;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1495,7 +1798,6 @@ static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
|
||||
|
||||
/* ------------------------------- */
|
||||
|
||||
|
||||
static void gpencil_draw_exit(bContext *C, wmOperator *op)
|
||||
{
|
||||
tGPsdata *p = op->customdata;
|
||||
@@ -1600,7 +1902,7 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
|
||||
break;
|
||||
case GP_PAINTMODE_DRAW:
|
||||
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw | "
|
||||
"ESC/Enter to end (or click outside this area)"));
|
||||
"E/ESC/Enter to end (or click outside this area)"));
|
||||
break;
|
||||
case GP_PAINTMODE_DRAW_POLY:
|
||||
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Poly Session: LMB click to place next stroke vertex | "
|
||||
@@ -1691,6 +1993,31 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
|
||||
*/
|
||||
p->mval[0] = event->mval[0] + 1;
|
||||
p->mval[1] = event->mval[1] + 1;
|
||||
|
||||
/* verify key status for straight lines */
|
||||
if ((event->ctrl > 0) || (event->alt > 0)) {
|
||||
if (p->straight[0] == 0) {
|
||||
int dx = abs(p->mval[0] - p->mvalo[0]);
|
||||
int dy = abs(p->mval[1] - p->mvalo[1]);
|
||||
if ((dx > 0) || (dy > 0)) {
|
||||
/* check mouse direction to replace the other coordinate with previous values */
|
||||
if (dx >= dy) {
|
||||
/* horizontal */
|
||||
p->straight[0] = 1;
|
||||
p->straight[1] = p->mval[1]; /* save y */
|
||||
}
|
||||
else {
|
||||
/* vertical */
|
||||
p->straight[0] = 2;
|
||||
p->straight[1] = p->mval[0]; /* save x */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
p->straight[0] = 0;
|
||||
}
|
||||
|
||||
p->curtime = PIL_check_seconds_timer();
|
||||
|
||||
/* handle pressure sensitivity (which is supplied by tablets) */
|
||||
@@ -1725,6 +2052,8 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
|
||||
p->mvalo[1] = p->mval[1];
|
||||
p->opressure = p->pressure;
|
||||
p->inittime = p->ocurtime = p->curtime;
|
||||
p->straight[0] = 0;
|
||||
p->straight[1] = 0;
|
||||
|
||||
/* special exception here for too high pressure values on first touch in
|
||||
* windows for some tablets, then we just skip first touch...
|
||||
@@ -1733,6 +2062,18 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if alt key is pressed and limit to straight lines */
|
||||
if (p->straight[0] != 0) {
|
||||
if (p->straight[0] == 1) {
|
||||
/* horizontal */
|
||||
p->mval[1] = p->straight[1]; /* replace y */
|
||||
}
|
||||
else {
|
||||
/* vertical */
|
||||
p->mval[0] = p->straight[1]; /* replace x */
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in stroke data (not actually used directly by gpencil_draw_apply) */
|
||||
RNA_collection_add(op->ptr, "stroke", &itemptr);
|
||||
|
||||
@@ -1855,7 +2196,6 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
|
||||
if (p->paintmode == GP_PAINTMODE_ERASER) {
|
||||
gpencil_draw_toggle_eraser_cursor(C, p, true);
|
||||
}
|
||||
|
||||
/* set cursor
|
||||
* NOTE: This may change later (i.e. intentionally via brush toggle,
|
||||
* or unintentionally if the user scrolls outside the area)...
|
||||
@@ -1870,6 +2210,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
|
||||
|
||||
/* handle the initial drawing - i.e. for just doing a simple dot */
|
||||
gpencil_draw_apply_event(op, event);
|
||||
op->flag |= OP_IS_MODAL_CURSOR_REGION;
|
||||
}
|
||||
else {
|
||||
/* toolbar invoked - don't start drawing yet... */
|
||||
@@ -1976,6 +2317,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
* is essential for ensuring that they can quickly return to that view
|
||||
*/
|
||||
}
|
||||
else if ((ELEM(event->type, DKEY)) && (event->val == KM_RELEASE)) {
|
||||
/* enable continuous if release D key in mid drawing */
|
||||
p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
}
|
||||
else {
|
||||
estate = OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
@@ -1986,7 +2331,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
/* exit painting mode (and/or end current stroke)
|
||||
* NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647]
|
||||
*/
|
||||
if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY)) {
|
||||
if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) {
|
||||
/* exit() ends the current stroke before cleaning up */
|
||||
/* printf("\t\tGP - end of paint op + end of stroke\n"); */
|
||||
p->status = GP_STATUS_DONE;
|
||||
@@ -2045,6 +2390,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
}
|
||||
else {
|
||||
/* printf("\t\tGP - end of stroke + op\n"); */
|
||||
/* disable paint session */
|
||||
p->scene->toolsettings->gpencil_flags &= ~GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
|
||||
p->status = GP_STATUS_DONE;
|
||||
estate = OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2074,6 +2422,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
in_bounds = true;
|
||||
}
|
||||
else {
|
||||
/* disable paint session */
|
||||
p->scene->toolsettings->gpencil_flags &= ~GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
|
||||
/* Out of bounds, or invalid in some other way */
|
||||
p->status = GP_STATUS_ERROR;
|
||||
estate = OPERATOR_CANCELLED;
|
||||
@@ -2090,6 +2441,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
in_bounds = BLI_rcti_isect_pt_v(®ion_rect, event->mval);
|
||||
}
|
||||
else {
|
||||
/* disable paint session */
|
||||
p->scene->toolsettings->gpencil_flags &= ~GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
|
||||
/* No region */
|
||||
p->status = GP_STATUS_ERROR;
|
||||
estate = OPERATOR_CANCELLED;
|
||||
@@ -2117,6 +2471,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
p = gpencil_stroke_begin(C, op);
|
||||
|
||||
if (p->status == GP_STATUS_ERROR) {
|
||||
/* disable paint session */
|
||||
p->scene->toolsettings->gpencil_flags &= ~GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
|
||||
estate = OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
@@ -2125,6 +2482,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
* NOTE: Don't eter this case if an error occurred while finding the
|
||||
* region (as above)
|
||||
*/
|
||||
/* disable paint session */
|
||||
p->scene->toolsettings->gpencil_flags &= ~GP_TOOL_FLAG_PAINTSESSIONS_ON;
|
||||
|
||||
p->status = GP_STATUS_DONE;
|
||||
estate = OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil.h"
|
||||
@@ -616,9 +617,10 @@ void GPENCIL_OT_select_less(wmOperatorType *ot)
|
||||
/* NOTE: Code here is adapted (i.e. copied directly) from gpencil_paint.c::gp_stroke_eraser_dostroke()
|
||||
* It would be great to de-duplicate the logic here sometime, but that can wait...
|
||||
*/
|
||||
static bool gp_stroke_do_circle_sel(bGPDstroke *gps, GP_SpaceConversion *gsc,
|
||||
const int mx, const int my, const int radius,
|
||||
const bool select, rcti *rect)
|
||||
static bool gp_stroke_do_circle_sel(
|
||||
bGPDstroke *gps, GP_SpaceConversion *gsc,
|
||||
const int mx, const int my, const int radius,
|
||||
const bool select, rcti *rect, const bool parented, float diff_mat[4][4])
|
||||
{
|
||||
bGPDspoint *pt1, *pt2;
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
@@ -626,7 +628,14 @@ static bool gp_stroke_do_circle_sel(bGPDstroke *gps, GP_SpaceConversion *gsc,
|
||||
bool changed = false;
|
||||
|
||||
if (gps->totpoints == 1) {
|
||||
gp_point_to_xy(gsc, gps, gps->points, &x0, &y0);
|
||||
if (!parented) {
|
||||
gp_point_to_xy(gsc, gps, gps->points, &x0, &y0);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt_temp;
|
||||
gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
|
||||
gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
|
||||
}
|
||||
|
||||
/* do boundbox check first */
|
||||
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
|
||||
@@ -654,9 +663,18 @@ static bool gp_stroke_do_circle_sel(bGPDstroke *gps, GP_SpaceConversion *gsc,
|
||||
/* get points to work with */
|
||||
pt1 = gps->points + i;
|
||||
pt2 = gps->points + i + 1;
|
||||
if (!parented) {
|
||||
gp_point_to_xy(gsc, gps, pt1, &x0, &y0);
|
||||
gp_point_to_xy(gsc, gps, pt2, &x1, &y1);
|
||||
}
|
||||
else {
|
||||
bGPDspoint npt;
|
||||
gp_point_to_parent_space(pt1, diff_mat, &npt);
|
||||
gp_point_to_xy(gsc, gps, &npt, &x0, &y0);
|
||||
|
||||
gp_point_to_xy(gsc, gps, pt1, &x0, &y0);
|
||||
gp_point_to_xy(gsc, gps, pt2, &x1, &y1);
|
||||
gp_point_to_parent_space(pt2, diff_mat, &npt);
|
||||
gp_point_to_xy(gsc, gps, &npt, &x1, &y1);
|
||||
}
|
||||
|
||||
/* check that point segment of the boundbox of the selection stroke */
|
||||
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
|
||||
@@ -733,11 +751,13 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
|
||||
|
||||
|
||||
/* find visible strokes, and select if hit */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
|
||||
{
|
||||
changed |= gp_stroke_do_circle_sel(gps, &gsc, mx, my, radius, select, &rect);
|
||||
changed |= gp_stroke_do_circle_sel(
|
||||
gps, &gsc, mx, my, radius, select, &rect,
|
||||
(gpl->parent != NULL), diff_mat);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
GP_EDITABLE_STROKES_END;
|
||||
|
||||
/* updates */
|
||||
if (changed) {
|
||||
@@ -818,8 +838,9 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
|
||||
WM_operator_properties_border_to_rcti(op, &rect);
|
||||
|
||||
/* select/deselect points */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
|
||||
{
|
||||
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
@@ -827,7 +848,14 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
|
||||
int x0, y0;
|
||||
|
||||
/* convert point coords to screenspace */
|
||||
gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
|
||||
if (gpl->parent == NULL) {
|
||||
gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt2;
|
||||
gp_point_to_parent_space(pt, diff_mat, &pt2);
|
||||
gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
|
||||
}
|
||||
|
||||
/* test if in selection rect */
|
||||
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) {
|
||||
@@ -845,7 +873,7 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
|
||||
/* Ensure that stroke selection is in sync with its points */
|
||||
gpencil_stroke_sync_selection(gps);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
GP_EDITABLE_STROKES_END;
|
||||
|
||||
/* updates */
|
||||
if (changed) {
|
||||
@@ -920,7 +948,7 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
/* select/deselect points */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
@@ -929,11 +957,17 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
|
||||
int x0, y0;
|
||||
|
||||
/* convert point coords to screenspace */
|
||||
gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
|
||||
|
||||
if (gpl->parent == NULL) {
|
||||
gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt2;
|
||||
gp_point_to_parent_space(pt, diff_mat, &pt2);
|
||||
gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0);
|
||||
}
|
||||
/* test if in lasso boundbox + within the lasso noose */
|
||||
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) &&
|
||||
BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
|
||||
BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
|
||||
{
|
||||
if (select) {
|
||||
pt->flag |= GP_SPOINT_SELECT;
|
||||
@@ -949,7 +983,7 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
|
||||
/* Ensure that stroke selection is in sync with its points */
|
||||
gpencil_stroke_sync_selection(gps);
|
||||
}
|
||||
CTX_DATA_END;
|
||||
GP_EDITABLE_STROKES_END;
|
||||
|
||||
/* cleanup */
|
||||
MEM_freeN((void *)mcords);
|
||||
@@ -1020,7 +1054,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* First Pass: Find stroke point which gets hit */
|
||||
/* XXX: maybe we should go from the top of the stack down instead... */
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
@@ -1029,7 +1063,14 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
int xy[2];
|
||||
|
||||
gp_point_to_xy(&gsc, gps, pt, &xy[0], &xy[1]);
|
||||
if (gpl->parent == NULL) {
|
||||
gp_point_to_xy(&gsc, gps, pt, &xy[0], &xy[1]);
|
||||
}
|
||||
else {
|
||||
bGPDspoint pt2;
|
||||
gp_point_to_parent_space(pt, diff_mat, &pt2);
|
||||
gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]);
|
||||
}
|
||||
|
||||
/* do boundbox check first */
|
||||
if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) {
|
||||
@@ -1040,14 +1081,14 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
|
||||
/* only use this point if it is a better match than the current hit - T44685 */
|
||||
if (pt_distance < hit_distance) {
|
||||
hit_stroke = gps;
|
||||
hit_point = pt;
|
||||
hit_point = pt;
|
||||
hit_distance = pt_distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
GP_EDITABLE_STROKES_END;
|
||||
|
||||
/* Abort if nothing hit... */
|
||||
if (ELEM(NULL, hit_stroke, hit_point)) {
|
||||
|
||||
@@ -142,7 +142,7 @@ void gpencil_undo_push(bGPdata *gpd)
|
||||
*/
|
||||
undo_node->gpd->adt = NULL;
|
||||
|
||||
BKE_gpencil_free(undo_node->gpd);
|
||||
BKE_gpencil_free(undo_node->gpd, false);
|
||||
MEM_freeN(undo_node->gpd);
|
||||
|
||||
BLI_freelinkN(&undo_nodes, undo_node);
|
||||
@@ -170,7 +170,7 @@ void gpencil_undo_finish(void)
|
||||
*/
|
||||
undo_node->gpd->adt = NULL;
|
||||
|
||||
BKE_gpencil_free(undo_node->gpd);
|
||||
BKE_gpencil_free(undo_node->gpd, false);
|
||||
MEM_freeN(undo_node->gpd);
|
||||
|
||||
undo_node = undo_node->next;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014, Blender Foundation
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -32,9 +32,13 @@
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLT_translation.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
@@ -46,6 +50,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_tracking.h"
|
||||
#include "BKE_action.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
@@ -269,6 +274,34 @@ int gp_active_layer_poll(bContext *C)
|
||||
return (gpl != NULL);
|
||||
}
|
||||
|
||||
/* poll callback for checking if there is an active brush */
|
||||
int gp_active_brush_poll(bContext *C)
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
bGPDbrush *brush = gpencil_brush_getactive(ts);
|
||||
|
||||
return (brush != NULL);
|
||||
}
|
||||
|
||||
/* poll callback for checking if there is an active palette */
|
||||
int gp_active_palette_poll(bContext *C)
|
||||
{
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
|
||||
return (palette != NULL);
|
||||
}
|
||||
|
||||
/* poll callback for checking if there is an active palette color */
|
||||
int gp_active_palettecolor_poll(bContext *C)
|
||||
{
|
||||
bGPdata *gpd = ED_gpencil_data_get_active(C);
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
bGPDpalettecolor *palcolor = gpencil_palettecolor_getactive(palette);
|
||||
|
||||
return (palcolor != NULL);
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
/* Dynamic Enums of GP Layers */
|
||||
/* NOTE: These include an option to create a new layer and use that... */
|
||||
@@ -412,6 +445,60 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
|
||||
return ED_gpencil_stroke_can_use_direct(sa, gps);
|
||||
}
|
||||
|
||||
/* Check whether given stroke can be edited for the current color */
|
||||
bool ED_gpencil_stroke_color_use(const bGPDlayer *gpl, const bGPDstroke *gps)
|
||||
{
|
||||
/* check if the color is editable */
|
||||
bGPDpalettecolor *palcolor = gps->palcolor;
|
||||
if (palcolor != NULL) {
|
||||
if (palcolor->flag & PC_COLOR_HIDE)
|
||||
return false;
|
||||
if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Get palette color or create a new one */
|
||||
bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps)
|
||||
{
|
||||
bGPDpalette *palette;
|
||||
bGPDpalettecolor *palcolor;
|
||||
|
||||
if ((gps->palcolor != NULL) && ((gps->flag & GP_STROKE_RECALC_COLOR) == 0))
|
||||
return gps->palcolor;
|
||||
|
||||
/* get palette */
|
||||
palette = gpencil_palette_getactive(gpd);
|
||||
if (palette == NULL) {
|
||||
palette = gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true);
|
||||
}
|
||||
/* get color */
|
||||
palcolor = gpencil_palettecolor_getbyname(palette, gps->colorname);
|
||||
if (palcolor == NULL) {
|
||||
if (gps->palcolor == NULL) {
|
||||
palcolor = gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
|
||||
/* set to a different color */
|
||||
ARRAY_SET_ITEMS(palcolor->color, 1.0f, 0.0f, 1.0f, 0.9f);
|
||||
}
|
||||
else {
|
||||
palcolor = gpencil_palettecolor_addnew(palette, gps->colorname, true);
|
||||
/* set old color and attributes */
|
||||
bGPDpalettecolor *gpscolor = gps->palcolor;
|
||||
copy_v4_v4(palcolor->color, gpscolor->color);
|
||||
copy_v4_v4(palcolor->fill, gpscolor->fill);
|
||||
palcolor->flag = gpscolor->flag;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear flag and set pointer */
|
||||
gps->flag &= ~GP_STROKE_RECALC_COLOR;
|
||||
gps->palcolor = palcolor;
|
||||
|
||||
return palcolor;
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
/* Space Conversion */
|
||||
|
||||
@@ -451,6 +538,50 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
|
||||
}
|
||||
}
|
||||
|
||||
/* convert point to parent space */
|
||||
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt)
|
||||
{
|
||||
float fpt[3];
|
||||
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
copy_v3_v3(&r_pt->x, fpt);
|
||||
}
|
||||
|
||||
/* Change position relative to parent object */
|
||||
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
/* undo matrix */
|
||||
float diff_mat[4][4];
|
||||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
for (i = 0; i < gps->totpoints; i++) {
|
||||
pt = &gps->points[i];
|
||||
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Change point position relative to parent object */
|
||||
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
|
||||
{
|
||||
/* undo matrix */
|
||||
float diff_mat[4][4];
|
||||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
}
|
||||
|
||||
/* Convert Grease Pencil points to screen-space values
|
||||
* WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
|
||||
@@ -591,20 +722,102 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
|
||||
madd_v3_v3fl(sco, &pt1->x, average_fac);
|
||||
madd_v3_v3fl(sco, &pt2->x, average_fac);
|
||||
|
||||
#if 0
|
||||
/* XXX: Disabled because get weird result */
|
||||
/* do pressure too? */
|
||||
if (affect_pressure) {
|
||||
pressure += pt1->pressure * average_fac;
|
||||
pressure += pt2->pressure * average_fac;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Based on influence factor, blend between original and optimal smoothed coordinate */
|
||||
interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
|
||||
|
||||
#if 0
|
||||
/* XXX: Disabled because get weird result */
|
||||
if (affect_pressure) {
|
||||
pt->pressure = pressure;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply smooth for strength to stroke point
|
||||
* \param gps Stroke to smooth
|
||||
* \param i Point index
|
||||
* \param inf Amount of smoothing to apply
|
||||
*/
|
||||
bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf)
|
||||
{
|
||||
bGPDspoint *ptb = &gps->points[i];
|
||||
|
||||
/* Do nothing if not enough points */
|
||||
if (gps->totpoints <= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compute theoretical optimal value using distances */
|
||||
bGPDspoint *pta, *ptc;
|
||||
int before = i - 1;
|
||||
int after = i + 1;
|
||||
|
||||
CLAMP_MIN(before, 0);
|
||||
CLAMP_MAX(after, gps->totpoints - 1);
|
||||
|
||||
pta = &gps->points[before];
|
||||
ptc = &gps->points[after];
|
||||
|
||||
/* the optimal value is the corresponding to the interpolation of the strength
|
||||
* at the distance of point b
|
||||
*/
|
||||
const float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
|
||||
const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength;
|
||||
|
||||
/* Based on influence factor, blend between original and optimal */
|
||||
ptb->strength = (1.0f - inf) * ptb->strength + inf * optimal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply smooth for thickness to stroke point (use pressure)
|
||||
* \param gps Stroke to smooth
|
||||
* \param i Point index
|
||||
* \param inf Amount of smoothing to apply
|
||||
*/
|
||||
bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf)
|
||||
{
|
||||
bGPDspoint *ptb = &gps->points[i];
|
||||
|
||||
/* Do nothing if not enough points */
|
||||
if (gps->totpoints <= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compute theoretical optimal value using distances */
|
||||
bGPDspoint *pta, *ptc;
|
||||
int before = i - 1;
|
||||
int after = i + 1;
|
||||
|
||||
CLAMP_MIN(before, 0);
|
||||
CLAMP_MAX(after, gps->totpoints - 1);
|
||||
|
||||
pta = &gps->points[before];
|
||||
ptc = &gps->points[after];
|
||||
|
||||
/* the optimal value is the corresponding to the interpolation of the pressure
|
||||
* at the distance of point b
|
||||
*/
|
||||
float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
|
||||
float optimal = (1.0f - fac) * pta->pressure + fac * ptc->pressure;
|
||||
|
||||
/* Based on influence factor, blend between original and optimal */
|
||||
ptb->pressure = (1.0f - inf) * ptb->pressure + inf * optimal;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -633,16 +846,99 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
|
||||
interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f);
|
||||
|
||||
pt->pressure = interpf(prev->pressure, next->pressure, 0.5f);
|
||||
pt->time = interpf(prev->time, next->time, 0.5f);
|
||||
pt->strength = interpf(prev->strength, next->strength, 0.5f);
|
||||
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
|
||||
pt->time = interpf(prev->time, next->time, 0.5f);
|
||||
}
|
||||
|
||||
/* Update to new total number of points */
|
||||
gps->totpoints = new_totpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add randomness to stroke
|
||||
* \param gps Stroke data
|
||||
* \param brsuh Brush data
|
||||
*/
|
||||
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush)
|
||||
{
|
||||
bGPDspoint *pt1, *pt2, *pt3;
|
||||
float v1[3];
|
||||
float v2[3];
|
||||
if (gps->totpoints < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get two vectors using 3 points */
|
||||
pt1 = &gps->points[0];
|
||||
pt2 = &gps->points[1];
|
||||
pt3 = &gps->points[(int)(gps->totpoints * 0.75)];
|
||||
|
||||
sub_v3_v3v3(v1, &pt2->x, &pt1->x);
|
||||
sub_v3_v3v3(v2, &pt3->x, &pt2->x);
|
||||
normalize_v3(v1);
|
||||
normalize_v3(v2);
|
||||
|
||||
/* get normal vector to plane created by two vectors */
|
||||
float normal[3];
|
||||
cross_v3_v3v3(normal, v1, v2);
|
||||
normalize_v3(normal);
|
||||
/* get orthogonal vector to plane to rotate random effect */
|
||||
float ortho[3];
|
||||
cross_v3_v3v3(ortho, v1, normal);
|
||||
normalize_v3(ortho);
|
||||
/* Read all points and apply shift vector (first and last point not modified) */
|
||||
for (int i = 1; i < gps->totpoints - 1; ++i) {
|
||||
bGPDspoint *pt = &gps->points[i];
|
||||
/* get vector with shift (apply a division because random is too sensitive */
|
||||
const float fac = BLI_frand() * (brush->draw_random_sub / 10.0f);
|
||||
float svec[3];
|
||||
copy_v3_v3(svec, ortho);
|
||||
if (BLI_frand() > 0.5f) {
|
||||
mul_v3_fl(svec, -fac);
|
||||
}
|
||||
else {
|
||||
mul_v3_fl(svec, fac);
|
||||
}
|
||||
|
||||
/* apply shift */
|
||||
add_v3_v3(&pt->x, svec);
|
||||
}
|
||||
|
||||
}
|
||||
/* calculate difference matrix */
|
||||
void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
|
||||
{
|
||||
Object *ob = gpl->parent;
|
||||
|
||||
if (ob == NULL) {
|
||||
unit_m4(diff_mat);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
|
||||
mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse);
|
||||
return;
|
||||
}
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, gpl->parsubstr);
|
||||
if (pchan) {
|
||||
float tmp_mat[4][4];
|
||||
mul_m4_m4m4(tmp_mat, ob->obmat, pchan->pose_mat);
|
||||
mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
|
||||
}
|
||||
else {
|
||||
mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse); /* if bone not found use object (armature) */
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
unit_m4(diff_mat); /* not defined type */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
|
||||
|
||||
bool ED_gpencil_stroke_minmax(
|
||||
const bGPDstroke *gps, const bool use_select,
|
||||
float r_min[3], float r_max[3])
|
||||
@@ -659,3 +955,74 @@ bool ED_gpencil_stroke_minmax(
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
/* Dynamic Enums of GP Brushes */
|
||||
|
||||
EnumPropertyItem *ED_gpencil_brushes_enum_itemf(
|
||||
bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
bGPDbrush *brush;
|
||||
EnumPropertyItem *item = NULL, item_tmp = { 0 };
|
||||
int totitem = 0;
|
||||
int i = 0;
|
||||
|
||||
if (ELEM(NULL, C, ts)) {
|
||||
return DummyRNA_DEFAULT_items;
|
||||
}
|
||||
|
||||
/* Existing brushes */
|
||||
for (brush = ts->gp_brushes.first; brush; brush = brush->next, i++) {
|
||||
item_tmp.identifier = brush->info;
|
||||
item_tmp.name = brush->info;
|
||||
item_tmp.value = i;
|
||||
|
||||
if (brush->flag & GP_BRUSH_ACTIVE)
|
||||
item_tmp.icon = ICON_BRUSH_DATA;
|
||||
else
|
||||
item_tmp.icon = ICON_NONE;
|
||||
|
||||
RNA_enum_item_add(&item, &totitem, &item_tmp);
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
|
||||
return item;
|
||||
}
|
||||
/* Dynamic Enums of GP Palettes */
|
||||
|
||||
EnumPropertyItem *ED_gpencil_palettes_enum_itemf(
|
||||
bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||
bGPDpalette *palette;
|
||||
EnumPropertyItem *item = NULL, item_tmp = { 0 };
|
||||
int totitem = 0;
|
||||
int i = 0;
|
||||
|
||||
if (ELEM(NULL, C, gpd)) {
|
||||
return DummyRNA_DEFAULT_items;
|
||||
}
|
||||
|
||||
/* Existing palettes */
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next, i++) {
|
||||
item_tmp.identifier = palette->info;
|
||||
item_tmp.name = palette->info;
|
||||
item_tmp.value = i;
|
||||
|
||||
if (palette->flag & PL_PALETTE_ACTIVE)
|
||||
item_tmp.icon = ICON_COLOR;
|
||||
else
|
||||
item_tmp.icon = ICON_NONE;
|
||||
|
||||
RNA_enum_item_add(&item, &totitem, &item_tmp);
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
|
||||
return item;
|
||||
}
|
||||
/* ******************************************************** */
|
||||
|
||||
@@ -41,6 +41,8 @@ struct bGPdata;
|
||||
struct bGPDlayer;
|
||||
struct bGPDframe;
|
||||
struct bGPDstroke;
|
||||
struct bGPDpalette;
|
||||
struct bGPDpalettecolor;
|
||||
struct bAnimContext;
|
||||
struct KeyframeEditData;
|
||||
struct PointerRNA;
|
||||
@@ -57,6 +59,7 @@ struct wmKeyConfig;
|
||||
typedef struct tGPspoint {
|
||||
int x, y; /* x and y coordinates of cursor (in relative to area) */
|
||||
float pressure; /* pressure of tablet at this point */
|
||||
float strength; /* pressure of tablet at this point for alpha factor */
|
||||
float time; /* Time relative to stroke start (used when converting to path) */
|
||||
} tGPspoint;
|
||||
|
||||
@@ -86,6 +89,9 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr
|
||||
|
||||
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *sa, const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_color_use(const struct bGPDlayer *gpl, const struct bGPDstroke *gps);
|
||||
|
||||
struct bGPDpalettecolor *ED_gpencil_stroke_getcolor(struct bGPdata *gpd, struct bGPDstroke *gps);
|
||||
|
||||
bool ED_gpencil_stroke_minmax(
|
||||
const struct bGPDstroke *gps, const bool use_select,
|
||||
@@ -142,4 +148,10 @@ bool ED_gpencil_anim_copybuf_paste(struct bAnimContext *ac, const short copy_mod
|
||||
int ED_gpencil_session_active(void);
|
||||
int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
|
||||
|
||||
/* ------------ Transformation Utilities ------------ */
|
||||
|
||||
/* get difference matrix using parent */
|
||||
void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]);
|
||||
|
||||
|
||||
#endif /* __ED_GPENCIL_H__ */
|
||||
|
||||
@@ -320,9 +320,9 @@ DEF_ICON(OUTLINER_OB_SPEAKER)
|
||||
DEF_ICON(BLANK123)
|
||||
DEF_ICON(BLANK124)
|
||||
DEF_ICON(BLANK125)
|
||||
DEF_ICON(BLANK126)
|
||||
DEF_ICON(BLANK127)
|
||||
#endif
|
||||
DEF_ICON(RESTRICT_COLOR_OFF)
|
||||
DEF_ICON(RESTRICT_COLOR_ON)
|
||||
DEF_ICON(RESTRICT_VIEW_OFF)
|
||||
DEF_ICON(RESTRICT_VIEW_ON)
|
||||
DEF_ICON(RESTRICT_SELECT_OFF)
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
@@ -1145,10 +1146,22 @@ static int object_delete_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1) {
|
||||
BKE_reportf(op->reports, RPT_WARNING,
|
||||
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
|
||||
base->object->id.name + 2, scene->id.name + 2);
|
||||
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
|
||||
base->object->id.name + 2, scene->id.name + 2);
|
||||
continue;
|
||||
}
|
||||
/* remove from Grease Pencil parent */
|
||||
for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
if (gpl->parent != NULL) {
|
||||
Object *ob = gpl->parent;
|
||||
Object *curob = base->object;
|
||||
if (ob == curob) {
|
||||
gpl->parent = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* deselect object -- it could be used in other scenes */
|
||||
base->object->flag &= ~SELECT;
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_vfont_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_listbase.h"
|
||||
@@ -1762,6 +1763,14 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
|
||||
else {
|
||||
/* copy already clears */
|
||||
}
|
||||
/* remap gpencil parenting */
|
||||
bGPdata *gpd = scene->gpd;
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
if (gpl->parent == ob) {
|
||||
gpl->parent = obn;
|
||||
}
|
||||
}
|
||||
|
||||
base->flag = obn->flag;
|
||||
|
||||
id_us_min(&ob->id);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_context.h"
|
||||
@@ -414,6 +415,99 @@ static void screen_opengl_render_write(OGLRender *oglrender)
|
||||
else printf("OpenGL Render failed to write '%s'\n", name);
|
||||
}
|
||||
|
||||
static void addAlphaOverFloat(float dest[4], const float source[4])
|
||||
{
|
||||
/* d = s + (1-alpha_s)d*/
|
||||
float mul;
|
||||
|
||||
mul = 1.0f - source[3];
|
||||
|
||||
dest[0] = (mul * dest[0]) + source[0];
|
||||
dest[1] = (mul * dest[1]) + source[1];
|
||||
dest[2] = (mul * dest[2]) + source[2];
|
||||
dest[3] = (mul * dest[3]) + source[3];
|
||||
|
||||
}
|
||||
|
||||
/* add renderlayer and renderpass for each grease pencil layer for using in composition */
|
||||
static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, RenderView *rv)
|
||||
{
|
||||
bGPdata *gpd = oglrender->scene->gpd;
|
||||
Scene *scene = oglrender->scene;
|
||||
|
||||
/* sanity checks */
|
||||
if (gpd == NULL) {
|
||||
return;
|
||||
}
|
||||
if (scene == NULL) {
|
||||
return;
|
||||
}
|
||||
if (BLI_listbase_is_empty(&gpd->layers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* save old alpha mode */
|
||||
short oldalphamode = scene->r.alphamode;
|
||||
/* set alpha transparent for gp */
|
||||
scene->r.alphamode = R_ALPHAPREMUL;
|
||||
|
||||
/* saves layer status */
|
||||
short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag");
|
||||
int i = 0;
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
oldsts[i] = gpl->flag;
|
||||
++i;
|
||||
}
|
||||
/* loop all layers to create separate render */
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* dont draw layer if hidden */
|
||||
if (gpl->flag & GP_LAYER_HIDE)
|
||||
continue;
|
||||
/* hide all layer except current */
|
||||
for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) {
|
||||
if (gpl != gph) {
|
||||
gph->flag |= GP_LAYER_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
/* render this gp layer */
|
||||
screen_opengl_render_doit(oglrender, rr);
|
||||
|
||||
/* add RendePass composite */
|
||||
RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name);
|
||||
|
||||
/* copy image data from rectf */
|
||||
float *src = RE_RenderViewGetById(rr, oglrender->view_id)->rectf;
|
||||
float *dest = rp->rect;
|
||||
|
||||
float *pixSrc, *pixDest;
|
||||
int x, y, rectx, recty;
|
||||
rectx = rr->rectx;
|
||||
recty = rr->recty;
|
||||
for (y = 0; y < recty; y++) {
|
||||
for (x = 0; x < rectx; x++) {
|
||||
pixSrc = src + 4 * (rectx * y + x);
|
||||
if (pixSrc[3] > 0.0) {
|
||||
pixDest = dest + 4 * (rectx * y + x);
|
||||
addAlphaOverFloat(pixDest, pixSrc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* back layer status */
|
||||
i = 0;
|
||||
for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) {
|
||||
gph->flag = oldsts[i];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
/* free memory */
|
||||
MEM_freeN(oldsts);
|
||||
|
||||
/* back default alpha mode */
|
||||
scene->r.alphamode = oldalphamode;
|
||||
}
|
||||
|
||||
static void screen_opengl_render_apply(OGLRender *oglrender)
|
||||
{
|
||||
RenderResult *rr;
|
||||
@@ -449,6 +543,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
|
||||
BLI_assert(view_id < oglrender->views_len);
|
||||
RE_SetActiveRenderView(oglrender->re, rv->name);
|
||||
oglrender->view_id = view_id;
|
||||
/* add grease pencil passes */
|
||||
add_gpencil_renderpass(oglrender, rr, rv);
|
||||
/* render composite */
|
||||
screen_opengl_render_doit(oglrender, rr);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,8 @@ const char *screen_context_dir[] = {
|
||||
"sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
|
||||
"gpencil_data", "gpencil_data_owner", /* grease pencil data */
|
||||
"visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
|
||||
"active_gpencil_layer", "active_gpencil_frame",
|
||||
"active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
|
||||
"active_gpencil_palettecolor", "active_gpencil_brush",
|
||||
"active_operator",
|
||||
NULL};
|
||||
|
||||
@@ -474,6 +475,44 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CTX_data_equals(member, "active_gpencil_palette")) {
|
||||
/* XXX: see comment for gpencil_data case... */
|
||||
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
|
||||
|
||||
if (gpd) {
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
|
||||
if (palette) {
|
||||
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPalette, palette);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CTX_data_equals(member, "active_gpencil_palettecolor")) {
|
||||
/* XXX: see comment for gpencil_data case... */
|
||||
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
|
||||
|
||||
if (gpd) {
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
|
||||
if (palette) {
|
||||
bGPDpalettecolor *palcolor = gpencil_palettecolor_getactive(palette);
|
||||
if (palcolor) {
|
||||
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPaletteColor, palcolor);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CTX_data_equals(member, "active_gpencil_brush")) {
|
||||
/* XXX: see comment for gpencil_data case... */
|
||||
bGPDbrush *brush = gpencil_brush_getactive(scene->toolsettings);
|
||||
|
||||
if (brush) {
|
||||
CTX_data_pointer_set(result, NULL, &RNA_GPencilBrush, brush);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (CTX_data_equals(member, "active_gpencil_frame")) {
|
||||
/* XXX: see comment for gpencil_data case... */
|
||||
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
|
||||
@@ -533,6 +572,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
||||
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1002,7 +1002,7 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
|
||||
|
||||
}
|
||||
|
||||
static void tselem_draw_gp_icon_uibut(struct DrawIconArg *arg, ID *id, bGPDlayer *gpl)
|
||||
static void UNUSED_FUNCTION(tselem_draw_gp_icon_uibut)(struct DrawIconArg *arg, ID *id, bGPDlayer *gpl)
|
||||
{
|
||||
/* restrict column clip - skip it for now... */
|
||||
if (arg->x >= arg->xmax) {
|
||||
@@ -1233,9 +1233,12 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
|
||||
else
|
||||
UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type));
|
||||
break;
|
||||
/* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */
|
||||
#if 0
|
||||
case TSE_GP_LAYER:
|
||||
tselem_draw_gp_icon_uibut(&arg, tselem->id, te->directdata);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
UI_icon_draw(x, y, ICON_DOT); break;
|
||||
}
|
||||
|
||||
@@ -327,6 +327,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
|
||||
for (j = 0; j < 3; j++) {
|
||||
copy_v3_v3(&pt->x, ruler_item->co[j]);
|
||||
pt->pressure = 1.0f;
|
||||
pt->strength = 1.0f;
|
||||
pt++;
|
||||
}
|
||||
}
|
||||
@@ -336,6 +337,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
|
||||
for (j = 0; j < 3; j += 2) {
|
||||
copy_v3_v3(&pt->x, ruler_item->co[j]);
|
||||
pt->pressure = 1.0f;
|
||||
pt->strength = 1.0f;
|
||||
pt++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7687,6 +7687,10 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
/* Proportional Editing... */
|
||||
@@ -7735,6 +7739,15 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDstroke *gps;
|
||||
float diff_mat[4][4];
|
||||
float inverse_diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
/* undo matrix */
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
}
|
||||
|
||||
/* Make a new frame to work on if the layer's frame and the current scene frame don't match up
|
||||
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
|
||||
@@ -7743,6 +7756,10 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
// XXX: should this be allowed when framelock is enabled?
|
||||
if (gpf->framenum != cfra) {
|
||||
gpf = gpencil_frame_addcopy(gpl, cfra);
|
||||
/* in some weird situations (framelock enabled) return NULL */
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over strokes, adding TransData for points as needed... */
|
||||
@@ -7755,7 +7772,10 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if the color is editable */
|
||||
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* What we need to include depends on proportional editing settings... */
|
||||
if (is_prop_edit) {
|
||||
if (is_prop_edit_connected) {
|
||||
@@ -7824,9 +7844,18 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
/* screenspace */
|
||||
td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
|
||||
|
||||
copy_m3_m4(td->smtx, t->persmat);
|
||||
copy_m3_m4(td->mtx, t->persinv);
|
||||
unit_m3(td->axismtx);
|
||||
/* apply parent transformations */
|
||||
if (gpl->parent == NULL) {
|
||||
copy_m3_m4(td->smtx, t->persmat);
|
||||
copy_m3_m4(td->mtx, t->persinv);
|
||||
unit_m3(td->axismtx);
|
||||
}
|
||||
else {
|
||||
/* apply matrix transformation relative to parent */
|
||||
copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
|
||||
copy_m3_m4(td->mtx, diff_mat); /* display position */
|
||||
copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* configure 2D dataspace points so that they don't play up... */
|
||||
@@ -7835,9 +7864,18 @@ static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
// XXX: matrices may need to be different?
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
unit_m3(td->axismtx); // XXX?
|
||||
/* apply parent transformations */
|
||||
if (gpl->parent == NULL) {
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
unit_m3(td->axismtx); // XXX?
|
||||
}
|
||||
else {
|
||||
/* apply matrix transformation relative to parent */
|
||||
copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */
|
||||
copy_m3_m4(td->mtx, diff_mat); /* display position */
|
||||
copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */
|
||||
}
|
||||
}
|
||||
/* Triangulation must be calculated again, so save the stroke for recalc function */
|
||||
td->extra = gps;
|
||||
|
||||
@@ -975,7 +975,9 @@ static void recalcData_gpencil_strokes(TransInfo *t)
|
||||
TransData *td = t->data;
|
||||
for (int i = 0; i < t->total; i++, td++) {
|
||||
bGPDstroke *gps = td->extra;
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
if (gps != NULL) {
|
||||
gps->flag |= GP_STROKE_RECALC_CACHES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_gpencil.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
@@ -68,6 +69,7 @@
|
||||
#include "ED_curve.h"
|
||||
#include "ED_particle.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
@@ -288,23 +290,48 @@ static int calc_manipulator_stats(const bContext *C)
|
||||
zero_v3(scene->twcent);
|
||||
|
||||
if (is_gp_edit) {
|
||||
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
|
||||
{
|
||||
/* we're only interested in selected points here... */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
float diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
/* Change selection status of all points, then make the stroke match */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
calc_tw_center(scene, &pt->x);
|
||||
totsel++;
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
/* only editable and visible layers are considered */
|
||||
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
/* calculate difference matrix if parent object */
|
||||
if (gpl->parent != NULL) {
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
}
|
||||
|
||||
for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we're only interested in selected points here... */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
/* Change selection status of all points, then make the stroke match */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
if (gpl->parent == NULL) {
|
||||
calc_tw_center(scene, &pt->x);
|
||||
totsel++;
|
||||
}
|
||||
else {
|
||||
mul_v3_m4v3(fpt, diff_mat, &pt->x);
|
||||
calc_tw_center(scene, fpt);
|
||||
totsel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
|
||||
/* selection center */
|
||||
if (totsel) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* The Original Code is Copyright (C) 2008, Blender Foundation.
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Joshua Leung
|
||||
* Contributor(s): Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -32,9 +32,10 @@
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
struct AnimData;
|
||||
|
||||
struct CurveMapping;
|
||||
|
||||
/* Grease-Pencil Annotations - 'Stroke Point'
|
||||
* -> Coordinates may either be 2d or 3d depending on settings at the time
|
||||
@@ -44,6 +45,7 @@ struct AnimData;
|
||||
typedef struct bGPDspoint {
|
||||
float x, y, z; /* co-ordinates of point (usually 2d, but can be 3d as well) */
|
||||
float pressure; /* pressure of input device (from 0 to 1) at this point */
|
||||
float strength; /* color strength (used for alpha factor) */
|
||||
float time; /* seconds since start of stroke */
|
||||
int flag; /* additional options (NOTE: can shrink this field down later if needed) */
|
||||
} bGPDspoint;
|
||||
@@ -65,24 +67,113 @@ typedef struct bGPDtriangle {
|
||||
int v1, v2, v3; /* indices for tesselated triangle used for GP Fill */
|
||||
} bGPDtriangle;
|
||||
|
||||
/* GP brush (used for new strokes) */
|
||||
typedef struct bGPDbrush {
|
||||
struct bGPDbrush *next, *prev;
|
||||
|
||||
char info[64]; /* Brush name. Must be unique. */
|
||||
short thickness; /* thickness to apply to strokes */
|
||||
short flag;
|
||||
float draw_smoothfac; /* amount of smoothing to apply to newly created strokes */
|
||||
short draw_smoothlvl; /* number of times to apply smooth factor to new strokes */
|
||||
short sublevel; /* number of times to subdivide new strokes */
|
||||
|
||||
float draw_sensitivity; /* amount of sensivity to apply to newly created strokes */
|
||||
float draw_strength; /* amount of alpha strength to apply to newly created strokes */
|
||||
float draw_jitter; /* amount of jitter to apply to newly created strokes */
|
||||
float draw_angle; /* angle when the brush has full thickness */
|
||||
float draw_angle_factor; /* factor to apply when angle change (only 90 degrees) */
|
||||
float draw_random_press; /* factor of randomness for sensitivity and strength */
|
||||
float draw_random_sub; /* factor of randomness for subdivision */
|
||||
struct CurveMapping *cur_sensitivity;
|
||||
struct CurveMapping *cur_strength;
|
||||
struct CurveMapping *cur_jitter;
|
||||
} bGPDbrush;
|
||||
|
||||
/* bGPDbrush->flag */
|
||||
typedef enum eGPDbrush_Flag {
|
||||
/* brush is active */
|
||||
GP_BRUSH_ACTIVE = (1 << 0),
|
||||
/* brush use pressure */
|
||||
GP_BRUSH_USE_PRESSURE = (1 << 1),
|
||||
/* brush use pressure for alpha factor */
|
||||
GP_BRUSH_USE_STENGTH_PRESSURE = (1 << 2),
|
||||
/* brush use pressure for alpha factor */
|
||||
GP_BRUSH_USE_JITTER_PRESSURE = (1 << 3),
|
||||
/* brush use random for pressure */
|
||||
GP_BRUSH_USE_RANDOM_PRESSURE = (1 << 4),
|
||||
/* brush use random for strength */
|
||||
GP_BRUSH_USE_RANDOM_STRENGTH = (1 << 5)
|
||||
} eGPDbrush_Flag;
|
||||
|
||||
/* color of palettes */
|
||||
typedef struct bGPDpalettecolor {
|
||||
struct bGPDpalettecolor *next, *prev;
|
||||
char info[64]; /* Color name. Must be unique. */
|
||||
float color[4];
|
||||
float fill[4]; /* color that should be used for drawing "fills" for strokes */
|
||||
short flag; /* settings for palette color */
|
||||
char pad[6]; /* padding for compiler alignment error */
|
||||
} bGPDpalettecolor;
|
||||
|
||||
/* bGPDpalettecolor->flag */
|
||||
typedef enum eGPDpalettecolor_Flag {
|
||||
/* color is active */
|
||||
PC_COLOR_ACTIVE = (1 << 0),
|
||||
/* don't display color */
|
||||
PC_COLOR_HIDE = (1 << 1),
|
||||
/* protected from further editing */
|
||||
PC_COLOR_LOCKED = (1 << 2),
|
||||
/* do onion skinning */
|
||||
PC_COLOR_ONIONSKIN = (1 << 3),
|
||||
/* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
|
||||
PC_COLOR_VOLUMETRIC = (1 << 4),
|
||||
/* Use High quality fill */
|
||||
PC_COLOR_HQ_FILL = (1 << 5)
|
||||
} eGPDpalettecolor_Flag;
|
||||
|
||||
/* palette of colors */
|
||||
typedef struct bGPDpalette {
|
||||
struct bGPDpalette *next, *prev;
|
||||
|
||||
/* pointer to individual colours */
|
||||
ListBase colors;
|
||||
char info[64]; /* Palette name. Must be unique. */
|
||||
|
||||
short flag;
|
||||
char pad[6]; /* padding for compiler alignment error */
|
||||
} bGPDpalette;
|
||||
|
||||
/* bGPDpalette->flag */
|
||||
typedef enum eGPDpalette_Flag {
|
||||
/* palette is active */
|
||||
PL_PALETTE_ACTIVE = (1 << 0)
|
||||
} eGPDpalette_Flag;
|
||||
|
||||
/* Grease-Pencil Annotations - 'Stroke'
|
||||
* -> A stroke represents a (simplified version) of the curve
|
||||
* drawn by the user in one 'mousedown'->'mouseup' operation
|
||||
*/
|
||||
typedef struct bGPDstroke {
|
||||
struct bGPDstroke *next, *prev;
|
||||
|
||||
bGPDspoint *points; /* array of data-points for stroke */
|
||||
void *pad; /* keep 4 pointers at the beginning, padding for 'inittime' is tricky 64/32bit */
|
||||
int totpoints; /* number of data-points in array */
|
||||
|
||||
short thickness; /* thickness of stroke (currently not used) */
|
||||
short flag; /* various settings about this stroke */
|
||||
|
||||
bGPDtriangle *triangles;/* tesselated triangles for GP Fill */
|
||||
int totpoints; /* number of data-points in array */
|
||||
int tot_triangles; /* number of triangles in array */
|
||||
int pad1, *pad2;
|
||||
|
||||
short thickness; /* thickness of stroke */
|
||||
short flag, pad[2]; /* various settings about this stroke */
|
||||
|
||||
double inittime; /* Init time of stroke */
|
||||
/* The pointer to color is only used during drawing, but not saved
|
||||
* colorname is the join with the palette, but when draw, the pointer is update if the value is NULL
|
||||
* to speed up the drawing
|
||||
*/
|
||||
char colorname[128]; /* color name */
|
||||
bGPDpalettecolor *palcolor; /* current palette color */
|
||||
/* temporary layer name only used during copy/paste to put the stroke in the original layer */
|
||||
char tmp_layerinfo[128];
|
||||
} bGPDstroke;
|
||||
|
||||
/* bGPDstroke->flag */
|
||||
@@ -97,6 +188,10 @@ typedef enum eGPDstroke_Flag {
|
||||
GP_STROKE_SELECT = (1 << 3),
|
||||
/* Recalculate triangulation for high quality fill (when true, force a new recalc) */
|
||||
GP_STROKE_RECALC_CACHES = (1 << 4),
|
||||
/* Recalculate the color pointer using the name as index (true force a new recalc) */
|
||||
GP_STROKE_RECALC_COLOR = (1 << 5),
|
||||
/* Flag used to indicate that stroke is closed and draw edge between last and first point */
|
||||
GP_STROKE_CYCLIC = (1 << 7),
|
||||
/* only for use with stroke-buffer (while drawing eraser) */
|
||||
GP_STROKE_ERASER = (1 << 15)
|
||||
} eGPDstroke_Flag;
|
||||
@@ -139,16 +234,18 @@ typedef struct bGPDlayer {
|
||||
float gcolor_prev[3]; /* optional color for ghosts before the active frame */
|
||||
float gcolor_next[3]; /* optional color for ghosts after the active frame */
|
||||
|
||||
float color[4]; /* color that should be used to draw all the strokes in this layer */
|
||||
float fill[4]; /* color that should be used for drawing "fills" for strokes */
|
||||
float color[4]; /* Color for strokes in layers (replaced by palettecolor). Only used for ruler (which uses GPencil internally) */
|
||||
float fill[4]; /* Fill color for strokes in layers. Not used and replaced by palettecolor fill */
|
||||
|
||||
char info[128]; /* optional reference info about this layer (i.e. "director's comments, 12/3")
|
||||
* this is used for the name of the layer too and kept unique. */
|
||||
|
||||
float draw_smoothfac; /* amount of smoothing to apply to newly created strokes */
|
||||
short draw_smoothlvl; /* number of times to apply smooth factor to new strokes */
|
||||
short sublevel; /* number of times to subdivide new strokes */
|
||||
short pad[4]; /* padding for compiler error */
|
||||
struct Object *parent; /* parent object */
|
||||
float inverse[4][4]; /* inverse matrix (only used if parented) */
|
||||
char parsubstr[64]; /* String describing subobject info, MAX_ID_NAME-2 */
|
||||
short partype, pad;
|
||||
float tintcolor[4]; /* Color used to tint layer, alpha value is used as factor */
|
||||
float opacity; /* Opacity of the layer */
|
||||
} bGPDlayer;
|
||||
|
||||
/* bGPDlayer->flag */
|
||||
@@ -176,7 +273,9 @@ typedef enum eGPDlayer_Flag {
|
||||
/* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
|
||||
GP_LAYER_VOLUMETRIC = (1 << 10),
|
||||
/* Use high quality fill (instead of buggy legacy OpenGL Fill) */
|
||||
GP_LAYER_HQ_FILL = (1 << 11)
|
||||
GP_LAYER_HQ_FILL = (1 << 11),
|
||||
/* Unlock color */
|
||||
GP_LAYER_UNLOCK_COLOR = (1 << 12)
|
||||
} eGPDlayer_Flag;
|
||||
|
||||
/* Grease-Pencil Annotations - 'DataBlock' */
|
||||
@@ -195,6 +294,13 @@ typedef struct bGPdata {
|
||||
short sbuffer_size; /* number of elements currently in cache */
|
||||
short sbuffer_sflag; /* flags for stroke that cache represents */
|
||||
void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
|
||||
float scolor[4]; /* buffer color using palettes */
|
||||
char pad[6]; /* padding for compiler alignment error */
|
||||
short sflag; /* settings for palette color */
|
||||
|
||||
/* saved paletes and brushes */
|
||||
ListBase palettes;
|
||||
//ListBase brushes;
|
||||
} bGPdata;
|
||||
|
||||
/* bGPdata->flag */
|
||||
@@ -229,7 +335,9 @@ typedef enum eGPdata_Flag {
|
||||
GP_DATA_STROKE_EDITMODE = (1 << 8),
|
||||
|
||||
/* Convenience/cache flag to make it easier to quickly toggle onion skinning on/off */
|
||||
GP_DATA_SHOW_ONIONSKINS = (1 << 9)
|
||||
GP_DATA_SHOW_ONIONSKINS = (1 << 9),
|
||||
/* Draw a green and red point to indicate start and end of the stroke */
|
||||
GP_DATA_SHOW_DIRECTION = (1 << 10)
|
||||
} eGPdata_Flag;
|
||||
|
||||
#endif /* __DNA_GPENCIL_TYPES_H__ */
|
||||
|
||||
@@ -62,6 +62,7 @@ struct AnimData;
|
||||
struct Editing;
|
||||
struct SceneStats;
|
||||
struct bGPdata;
|
||||
struct bGPDbrush;
|
||||
struct MovieClip;
|
||||
struct ColorSpace;
|
||||
|
||||
@@ -1117,12 +1118,12 @@ typedef enum eGP_EditBrush_Types {
|
||||
GP_EDITBRUSH_TYPE_SUBDIVIDE = 7,
|
||||
GP_EDITBRUSH_TYPE_SIMPLIFY = 8,
|
||||
GP_EDITBRUSH_TYPE_CLONE = 9,
|
||||
GP_EDITBRUSH_TYPE_STRENGTH = 10,
|
||||
|
||||
/* !!! Update GP_EditBrush_Data brush[###]; below !!! */
|
||||
TOT_GP_EDITBRUSH_TYPES
|
||||
} eGP_EditBrush_Types;
|
||||
|
||||
|
||||
/* Settings for a GPencil Stroke Sculpting Brush */
|
||||
typedef struct GP_EditBrush_Data {
|
||||
short size; /* radius of brush */
|
||||
@@ -1148,17 +1149,26 @@ typedef enum eGP_EditBrush_Flag {
|
||||
|
||||
/* GPencil Stroke Sculpting Settings */
|
||||
typedef struct GP_BrushEdit_Settings {
|
||||
GP_EditBrush_Data brush[10]; /* TOT_GP_EDITBRUSH_TYPES */
|
||||
GP_EditBrush_Data brush[11]; /* TOT_GP_EDITBRUSH_TYPES */
|
||||
void *paintcursor; /* runtime */
|
||||
|
||||
int brushtype; /* eGP_EditBrush_Types */
|
||||
int flag; /* eGP_BrushEdit_SettingsFlag */
|
||||
char pad[4];
|
||||
float alpha; /* alpha factor for selection color */
|
||||
} GP_BrushEdit_Settings;
|
||||
|
||||
/* GP_BrushEdit_Settings.flag */
|
||||
typedef enum eGP_BrushEdit_SettingsFlag {
|
||||
/* only affect selected points */
|
||||
GP_BRUSHEDIT_FLAG_SELECT_MASK = (1 << 0)
|
||||
GP_BRUSHEDIT_FLAG_SELECT_MASK = (1 << 0),
|
||||
/* apply brush to position */
|
||||
GP_BRUSHEDIT_FLAG_APPLY_POSITION = (1 << 1),
|
||||
/* apply brush to strength */
|
||||
GP_BRUSHEDIT_FLAG_APPLY_STRENGTH = (1 << 2),
|
||||
/* apply brush to thickness */
|
||||
GP_BRUSHEDIT_FLAG_APPLY_THICKNESS = (1 << 3)
|
||||
|
||||
} eGP_BrushEdit_SettingsFlag;
|
||||
|
||||
/* *************************************************************** */
|
||||
@@ -1378,6 +1388,9 @@ typedef struct ToolSettings {
|
||||
/* Grease Pencil Sculpt */
|
||||
struct GP_BrushEdit_Settings gp_sculpt;
|
||||
|
||||
/* Grease Pencil Drawing Brushes (bGPDbrush) */
|
||||
ListBase gp_brushes;
|
||||
|
||||
/* Image Paint (8 byttse aligned please!) */
|
||||
struct ImagePaintSettings imapaint;
|
||||
|
||||
|
||||
@@ -257,6 +257,9 @@ extern StructRNA RNA_FreestyleSettings;
|
||||
extern StructRNA RNA_Function;
|
||||
extern StructRNA RNA_GPencilFrame;
|
||||
extern StructRNA RNA_GPencilLayer;
|
||||
extern StructRNA RNA_GPencilPalette;
|
||||
extern StructRNA RNA_GPencilPaletteColor;
|
||||
extern StructRNA RNA_GPencilBrush;
|
||||
extern StructRNA RNA_GPencilStroke;
|
||||
extern StructRNA RNA_GPencilStrokePoint;
|
||||
extern StructRNA RNA_GPencilSculptSettings;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Blender Foundation (2009), Joshua Leung
|
||||
* Contributor(s): Blender Foundation (2009), Joshua Leung, Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -41,6 +41,17 @@
|
||||
#include "rna_internal.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
/* parent type */
|
||||
static EnumPropertyItem parent_type_items[] = {
|
||||
{PAROBJECT, "OBJECT", 0, "Object", "The layer is parented to an object"},
|
||||
{PARSKEL, "ARMATURE", 0, "Armature", ""},
|
||||
{PARBONE, "BONE", 0, "Bone", "The layer is parented to a bone"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
@@ -49,8 +60,7 @@
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "BKE_gpencil.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "BKE_action.h"
|
||||
|
||||
|
||||
static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
|
||||
@@ -90,6 +100,16 @@ static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, Pointer
|
||||
rna_GPencil_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_GPencil_stroke_colorname_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bGPDstroke *gps = (bGPDstroke *)ptr->data;
|
||||
gps->flag |= GP_STROKE_RECALC_COLOR;
|
||||
gps->palcolor = NULL;
|
||||
|
||||
/* Now do standard updates... */
|
||||
rna_GPencil_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static char *rna_GPencilLayer_path(PointerRNA *ptr)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
@@ -123,38 +143,140 @@ static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *ma
|
||||
* it's relatively hard to test for that. So, for now, only volumetric strokes
|
||||
* get to be larger...
|
||||
*/
|
||||
|
||||
/* From GP v2 this value is used to increase or decrease the thickness of the stroke */
|
||||
if (gpl->flag & GP_LAYER_VOLUMETRIC) {
|
||||
*min = 1;
|
||||
*min = -300;
|
||||
*max = 300;
|
||||
|
||||
*softmin = 1;
|
||||
*softmin = -100;
|
||||
*softmax = 100;
|
||||
}
|
||||
else {
|
||||
*min = 1;
|
||||
*min = -10;
|
||||
*max = 10;
|
||||
|
||||
*softmin = 1;
|
||||
*softmin = -10;
|
||||
*softmax = 10;
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_GPencilLayer_is_stroke_visible_get(PointerRNA *ptr)
|
||||
/* set parent */
|
||||
static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *substr)
|
||||
{
|
||||
/* see drawgpencil.c -> gp_draw_data_layers() for more details
|
||||
* about this limit for showing/not showing
|
||||
*/
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
return (gpl->color[3] > GPENCIL_ALPHA_OPACITY_THRESH);
|
||||
if (type == PAROBJECT) {
|
||||
invert_m4_m4(gpl->inverse, par->obmat);
|
||||
gpl->parent = par;
|
||||
gpl->partype |= PAROBJECT;
|
||||
gpl->parsubstr[0] = 0;
|
||||
}
|
||||
else if (type == PARSKEL) {
|
||||
invert_m4_m4(gpl->inverse, par->obmat);
|
||||
gpl->parent = par;
|
||||
gpl->partype |= PARSKEL;
|
||||
gpl->parsubstr[0] = 0;
|
||||
}
|
||||
else if (type == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, substr);
|
||||
if (pchan) {
|
||||
float tmp_mat[4][4];
|
||||
mul_m4_m4m4(tmp_mat, par->obmat, pchan->pose_mat);
|
||||
|
||||
invert_m4_m4(gpl->inverse, tmp_mat);
|
||||
gpl->parent = par;
|
||||
gpl->partype |= PARBONE;
|
||||
BLI_strncpy(gpl->parsubstr, substr, sizeof(gpl->parsubstr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_GPencilLayer_is_fill_visible_get(PointerRNA *ptr)
|
||||
/* set parent object and inverse matrix */
|
||||
static void rna_GPencilLayer_parent_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
/* see drawgpencil.c -> gp_draw_data_layers() for more details
|
||||
* about this limit for showing/not showing
|
||||
*/
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
return (gpl->fill[3] > GPENCIL_ALPHA_OPACITY_THRESH);
|
||||
Object *par = (Object *)value.data;
|
||||
|
||||
if (par != NULL) {
|
||||
set_parent(gpl, par, gpl->partype, gpl->parsubstr);
|
||||
}
|
||||
else {
|
||||
/* keep strokes in the same place, so apply current transformation */
|
||||
if (gpl->parent != NULL) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
float diff_mat[4][4];
|
||||
/* calculate difference matrix */
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(diff_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* clear parent */
|
||||
gpl->parent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* set parent type */
|
||||
static void rna_GPencilLayer_parent_type_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
Object *par = gpl->parent;
|
||||
gpl->partype = value;
|
||||
|
||||
if (par != NULL) {
|
||||
set_parent(gpl, par, value, gpl->parsubstr);
|
||||
}
|
||||
}
|
||||
|
||||
/* set parent bone */
|
||||
static void rna_GPencilLayer_parent_bone_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
|
||||
Object *par = gpl->parent;
|
||||
gpl->partype = PARBONE;
|
||||
|
||||
if (par != NULL) {
|
||||
set_parent(gpl, par, gpl->partype, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* parent types enum */
|
||||
static EnumPropertyItem *rna_Object_parent_type_itemf(
|
||||
bContext *UNUSED(C), PointerRNA *ptr,
|
||||
PropertyRNA *UNUSED(prop), bool *r_free)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
EnumPropertyItem *item = NULL;
|
||||
int totitem = 0;
|
||||
|
||||
RNA_enum_items_add_value(&item, &totitem, parent_type_items, PAROBJECT);
|
||||
|
||||
if (gpl->parent) {
|
||||
Object *par = gpl->parent;
|
||||
|
||||
if (par->type == OB_ARMATURE) {
|
||||
/* special hack: prevents this being overrided */
|
||||
RNA_enum_items_add_value(&item, &totitem, &parent_type_items[1], PARSKEL);
|
||||
RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARBONE);
|
||||
}
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static int rna_GPencilLayer_is_parented_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
return (gpl->parent != NULL);
|
||||
}
|
||||
|
||||
static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr)
|
||||
@@ -357,10 +479,12 @@ static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame)
|
||||
static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame, const char *colorname)
|
||||
{
|
||||
bGPDstroke *stroke = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
|
||||
|
||||
strcpy(stroke->colorname, colorname);
|
||||
stroke->palcolor = NULL;
|
||||
stroke->flag |= GP_STROKE_RECALC_COLOR;
|
||||
BLI_addtail(&frame->strokes, stroke);
|
||||
|
||||
return stroke;
|
||||
@@ -490,6 +614,239 @@ static void rna_GPencil_clear(bGPdata *gpd)
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
/* Palettes */
|
||||
static bGPDpalette *rna_GPencil_palette_new(bGPdata *gpd, const char *name, int setactive)
|
||||
{
|
||||
bGPDpalette *palette = gpencil_palette_addnew(gpd, name, setactive != 0);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
static void rna_GPencil_palette_remove(bGPdata *gpd, ReportList *reports, PointerRNA *palette_ptr)
|
||||
{
|
||||
bGPDpalette *palette = palette_ptr->data;
|
||||
if (BLI_findindex(&gpd->palettes, palette) == -1) {
|
||||
BKE_report(reports, RPT_ERROR, "Palette not found in grease pencil data");
|
||||
return;
|
||||
}
|
||||
|
||||
gpencil_palette_delete(gpd, palette);
|
||||
RNA_POINTER_INVALIDATE(palette_ptr);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static PointerRNA rna_GPencil_active_palette_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPdata *gpd = ptr->id.data;
|
||||
|
||||
if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */
|
||||
bGPDpalette *palette;
|
||||
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
if (palette->flag & PL_PALETTE_ACTIVE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (palette) {
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_GPencilPalette, palette);
|
||||
}
|
||||
}
|
||||
|
||||
return rna_pointer_inherit_refine(ptr, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rna_GPencil_active_palette_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
bGPdata *gpd = ptr->id.data;
|
||||
|
||||
if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */
|
||||
bGPDpalette *palette;
|
||||
|
||||
for (palette = gpd->palettes.first; palette; palette = palette->next) {
|
||||
if (palette == value.data) {
|
||||
palette->flag |= PL_PALETTE_ACTIVE;
|
||||
}
|
||||
else {
|
||||
palette->flag &= ~PL_PALETTE_ACTIVE;
|
||||
}
|
||||
}
|
||||
/* force color recalc */
|
||||
gpencil_palette_change_strokes(gpd);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_GPencilPalette_index_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ptr->id.data;
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
|
||||
return BLI_findindex(&gpd->palettes, palette);
|
||||
}
|
||||
|
||||
static void rna_GPencilPalette_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ptr->id.data;
|
||||
bGPDpalette *palette = BLI_findlink(&gpd->palettes, value);
|
||||
|
||||
gpencil_palette_setactive(gpd, palette);
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void rna_GPencilPalette_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ptr->id.data;
|
||||
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&gpd->palettes) - 1);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
}
|
||||
|
||||
/* Palette colors */
|
||||
static bGPDpalettecolor *rna_GPencilPalette_color_new(bGPDpalette *palette)
|
||||
{
|
||||
bGPDpalettecolor *color = gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static void rna_GPencilPalette_color_remove(bGPDpalette *palette, ReportList *reports, PointerRNA *color_ptr)
|
||||
{
|
||||
bGPDpalettecolor *color = color_ptr->data;
|
||||
|
||||
if (BLI_findindex(&palette->colors, color) == -1) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Palette '%s' does not contain color given", palette->info + 2);
|
||||
return;
|
||||
}
|
||||
|
||||
gpencil_palettecolor_delete(palette, color);
|
||||
RNA_POINTER_INVALIDATE(color_ptr);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static PointerRNA rna_GPencilPalette_active_color_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPDpalette *palette = (bGPDpalette *)ptr->data;
|
||||
bGPDpalettecolor *color;
|
||||
|
||||
for (color = palette->colors.first; color; color = color->next) {
|
||||
if (color->flag & PC_COLOR_ACTIVE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (color) {
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_GPencilPaletteColor, color);
|
||||
}
|
||||
|
||||
return rna_pointer_inherit_refine(ptr, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rna_GPencilPalette_active_color_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
bGPDpalette *palette = (bGPDpalette *)ptr->data;
|
||||
bGPDpalettecolor *color = value.data;
|
||||
|
||||
gpencil_palettecolor_setactive(palette, color);
|
||||
}
|
||||
|
||||
static void rna_GPencilPalette_info_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bGPdata *gpd = ptr->id.data;
|
||||
bGPDpalette *palette = ptr->data;
|
||||
|
||||
/* copy the new name into the name slot */
|
||||
BLI_strncpy_utf8(palette->info, value, sizeof(palette->info));
|
||||
|
||||
BLI_uniquename(&gpd->palettes, palette, DATA_("GP_Palette"), '.', offsetof(bGPDpalette, info),
|
||||
sizeof(palette->info));
|
||||
}
|
||||
|
||||
static char *rna_GPencilPalette_color_path(PointerRNA *ptr)
|
||||
{
|
||||
bGPdata *gpd = ptr->id.data;
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
bGPDpalettecolor *palcolor = ptr->data;
|
||||
|
||||
char name_palette[sizeof(palette->info) * 2];
|
||||
char name_color[sizeof(palcolor->info) * 2];
|
||||
|
||||
BLI_strescape(name_palette, palette->info, sizeof(name_palette));
|
||||
BLI_strescape(name_color, palcolor->info, sizeof(name_color));
|
||||
|
||||
return BLI_sprintfN("palettes[\"%s\"].colors[\"%s\"]", name_palette, name_color);
|
||||
}
|
||||
|
||||
static void rna_GPencilPaletteColor_info_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bGPdata *gpd = ptr->id.data;
|
||||
bGPDpalette *palette = gpencil_palette_getactive(gpd);
|
||||
bGPDpalettecolor *palcolor = ptr->data;
|
||||
|
||||
/* rename all strokes */
|
||||
gpencil_palettecolor_changename(gpd, palcolor->info, value);
|
||||
|
||||
/* copy the new name into the name slot */
|
||||
BLI_strncpy_utf8(palcolor->info, value, sizeof(palcolor->info));
|
||||
BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info),
|
||||
sizeof(palcolor->info));
|
||||
}
|
||||
|
||||
static void rna_GPencilStrokeColor_info_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bGPDstroke *gps = ptr->data;
|
||||
|
||||
/* copy the new name into the name slot */
|
||||
BLI_strncpy_utf8(gps->colorname, value, sizeof(gps->colorname));
|
||||
}
|
||||
|
||||
|
||||
static int rna_GPencilPaletteColor_is_stroke_visible_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPDpalettecolor *pcolor = (bGPDpalettecolor *)ptr->data;
|
||||
return (pcolor->color[3] > GPENCIL_ALPHA_OPACITY_THRESH);
|
||||
}
|
||||
|
||||
static int rna_GPencilPaletteColor_is_fill_visible_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPDpalettecolor *pcolor = (bGPDpalettecolor *)ptr->data;
|
||||
return (pcolor->fill[3] > GPENCIL_ALPHA_OPACITY_THRESH);
|
||||
}
|
||||
|
||||
static int rna_GPencilPaletteColor_index_get(PointerRNA *ptr)
|
||||
{
|
||||
bGPDpalette *palette = (bGPDpalette *)ptr->data;
|
||||
bGPDpalettecolor *pcolor = gpencil_palettecolor_getactive(palette);
|
||||
|
||||
return BLI_findindex(&palette->colors, pcolor);
|
||||
}
|
||||
|
||||
static void rna_GPencilPaletteColor_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bGPDpalette *palette = (bGPDpalette *)ptr->data;
|
||||
bGPDpalettecolor *pcolor = BLI_findlink(&palette->colors, value);
|
||||
gpencil_palettecolor_setactive(palette, pcolor);
|
||||
}
|
||||
|
||||
static void rna_GPencilPaletteColor_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
|
||||
{
|
||||
bGPDpalette *palette = (bGPDpalette *)ptr->data;
|
||||
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&palette->colors) - 1);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
|
||||
@@ -513,6 +870,12 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "strength");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Strength", "Color intensity (alpha factor)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SPOINT_SELECT);
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_point_select_set");
|
||||
@@ -542,6 +905,35 @@ static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cpr
|
||||
RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
/* This information is read only and it can be used by add-ons */
|
||||
static void rna_def_gpencil_triangle(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GPencilTriangle", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPDtriangle");
|
||||
RNA_def_struct_ui_text(srna, "Triangle", "Triangulation data for HQ fill");
|
||||
|
||||
/* point v1 */
|
||||
prop = RNA_def_property(srna, "v1", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "v1");
|
||||
RNA_def_property_ui_text(prop, "v1", "First triangle vertice index");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
/* point v2 */
|
||||
prop = RNA_def_property(srna, "v2", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "v2");
|
||||
RNA_def_property_ui_text(prop, "v2", "Second triangle vertice index");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
/* point v3 */
|
||||
prop = RNA_def_property(srna, "v3", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "v3");
|
||||
RNA_def_property_ui_text(prop, "v3", "Third triangle vertice index");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_stroke(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -566,6 +958,19 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points");
|
||||
rna_def_gpencil_stroke_points_api(brna, prop);
|
||||
|
||||
/* Triangles */
|
||||
prop = RNA_def_property(srna, "triangles", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "triangles", "tot_triangles");
|
||||
RNA_def_property_struct_type(prop, "GPencilTriangle");
|
||||
RNA_def_property_ui_text(prop, "Triangles", "Triangulation data for HQ fill");
|
||||
|
||||
/* Color */
|
||||
prop = RNA_def_property(srna, "color", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GPencilPaletteColor");
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "palcolor");
|
||||
RNA_def_property_ui_text(prop, "Palette Color", "Color from palette used in Stroke");
|
||||
RNA_def_property_update(prop, 0, "rna_GPencil_update");
|
||||
|
||||
/* Settings */
|
||||
prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
|
||||
@@ -578,6 +983,27 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_select_set");
|
||||
RNA_def_property_ui_text(prop, "Select", "Stroke is selected for viewport editing");
|
||||
RNA_def_property_update(prop, 0, "rna_GPencil_update");
|
||||
|
||||
/* Color Name */
|
||||
prop = RNA_def_property(srna, "colorname", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilStrokeColor_info_set");
|
||||
RNA_def_property_ui_text(prop, "Color Name", "Palette color name");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_stroke_colorname_update");
|
||||
|
||||
/* Cyclic: Draw a line from end to start point */
|
||||
prop = RNA_def_property(srna, "draw_cyclic", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_CYCLIC);
|
||||
RNA_def_property_ui_text(prop, "Cyclic", "Enable cyclic drawing, closing the stroke");
|
||||
RNA_def_property_update(prop, 0, "rna_GPencil_update");
|
||||
|
||||
/* Line Thickness */
|
||||
prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_int_sdna(prop, NULL, "thickness");
|
||||
RNA_def_property_range(prop, 1, 300);
|
||||
RNA_def_property_ui_range(prop, 1, 10, 1, 0);
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Thickness of stroke (in pixels)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
@@ -594,6 +1020,7 @@ static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new");
|
||||
RNA_def_function_ui_description(func, "Add a new grease pencil stroke");
|
||||
parm = RNA_def_string(func, "colorname", 0, MAX_NAME, "Color", "Name of the color");
|
||||
parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
@@ -721,45 +1148,33 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in a volumetric effect");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Use High Quality Fill */
|
||||
prop = RNA_def_property(srna, "use_hq_fill", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HQ_FILL);
|
||||
RNA_def_property_ui_text(prop, "High Quality Fill", "Fill strokes using high quality method to avoid glitches (slower fps during animation playback)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Stroke Drawing Color */
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Color", "Color for all strokes in this layer");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "color[3]");
|
||||
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "opacity");
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Fill Drawing Color */
|
||||
prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fill");
|
||||
/* Tint Color */
|
||||
prop = RNA_def_property(srna, "tint_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_float_sdna(prop, NULL, "tintcolor");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke");
|
||||
RNA_def_property_ui_text(prop, "Tint Color", "Color for tinting stroke colors");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fill_alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fill[3]");
|
||||
/* Tint factor */
|
||||
prop = RNA_def_property(srna, "tint_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "tintcolor[3]");
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Fill Opacity", "Opacity for filling region bounded by each stroke");
|
||||
RNA_def_property_ui_text(prop, "Tint Factor", "Factor of tinting color");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Line Thickness */
|
||||
prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL);
|
||||
/* Line Thickness change */
|
||||
prop = RNA_def_property(srna, "line_change", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_int_sdna(prop, NULL, "thickness");
|
||||
//RNA_def_property_range(prop, 1, 10); /* 10 px limit comes from Windows OpenGL limits for natively-drawn strokes */
|
||||
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_GPencilLayer_line_width_range");
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)");
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Thickness change to apply current strokes (in pixels)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Onion-Skinning */
|
||||
@@ -803,31 +1218,6 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Smoothing factor for new strokes */
|
||||
prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac");
|
||||
RNA_def_property_range(prop, 0.0, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "Smooth",
|
||||
"Amount of smoothing to apply to newly created strokes, to reduce jitter/noise");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Iterations of the Smoothing factor */
|
||||
prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl");
|
||||
RNA_def_property_range(prop, 1, 3);
|
||||
RNA_def_property_ui_text(prop, "Iterations",
|
||||
"Number of times to smooth newly created strokes "
|
||||
"(smoothing strength is halved on each successive round of smoothing)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Subdivision level for new strokes */
|
||||
prop = RNA_def_property(srna, "pen_subdivision_steps", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "sublevel");
|
||||
RNA_def_property_range(prop, 0, 3);
|
||||
RNA_def_property_ui_text(prop, "Subdivision Steps",
|
||||
"Number of times to subdivide newly created strokes, for less jagged strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Flags */
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
|
||||
@@ -847,6 +1237,15 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Frame Locked", "Lock current frame displayed by layer");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Unlock colors */
|
||||
prop = RNA_def_property(srna, "unlock_color", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_UNLOCK_COLOR);
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_COLOR_OFF, 1);
|
||||
RNA_def_property_ui_text(prop, "Unlock color", "Unprotect colors selected from further editing "
|
||||
"and/or frame changes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
|
||||
/* expose as layers.active */
|
||||
#if 0
|
||||
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
|
||||
@@ -873,17 +1272,41 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Parent object */
|
||||
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_GPencilLayer_parent_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_ui_text(prop, "Parent", "Parent Object");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Read-only state props (for simpler UI code) */
|
||||
prop = RNA_def_property(srna, "is_stroke_visible", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_stroke_visible_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Is Stroke Visible", "True when opacity of stroke is set high enough to be visible");
|
||||
/* parent type */
|
||||
prop = RNA_def_property(srna, "parent_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "partype");
|
||||
RNA_def_property_enum_items(prop, parent_type_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, "rna_GPencilLayer_parent_type_set", "rna_Object_parent_type_itemf");
|
||||
RNA_def_property_ui_text(prop, "Parent Type", "Type of parent relation");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "is_fill_visible", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_fill_visible_get", NULL);
|
||||
/* parent bone */
|
||||
prop = RNA_def_property(srna, "parent_bone", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "parsubstr");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilLayer_parent_bone_set");
|
||||
RNA_def_property_ui_text(prop, "Parent Bone", "Name of parent bone in case of a bone parenting relation");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* matrix */
|
||||
prop = RNA_def_property(srna, "matrix_inverse", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "inverse");
|
||||
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "MatrixInverse", "Parent inverse transformation matrix");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* read only parented flag */
|
||||
prop = RNA_def_property(srna, "is_parented", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_parented_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible");
|
||||
RNA_def_property_ui_text(prop, "Is Parented", "True when the layer parent object is set");
|
||||
|
||||
/* Layers API */
|
||||
func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear");
|
||||
@@ -933,6 +1356,207 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_palettecolor(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GPencilPaletteColor", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPDpalettecolor");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Palette color", "Collection of related colors");
|
||||
RNA_def_struct_path_func(srna, "rna_GPencilPalette_color_path");
|
||||
|
||||
/* Stroke Drawing Color */
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_float_sdna(prop, NULL, "color");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Color", "Color for strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "color[3]");
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Opacity", "Color Opacity");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Name */
|
||||
prop = RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Info", "Color name");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilPaletteColor_info_set");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Fill Drawing Color */
|
||||
prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fill");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Fill alpha */
|
||||
prop = RNA_def_property(srna, "fill_alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fill[3]");
|
||||
RNA_def_property_range(prop, 0.0, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Fill Opacity", "Opacity for filling region bounded by each stroke");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Flags */
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_HIDE);
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
|
||||
RNA_def_property_ui_text(prop, "Hide", "Set color Visibility");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_LOCKED);
|
||||
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
|
||||
RNA_def_property_ui_text(prop, "Locked", "Protect color from further editing and/or frame changes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "ghost", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_ONIONSKIN);
|
||||
RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0);
|
||||
RNA_def_property_ui_text(prop, "Ghost", "Display the color in onion skinning");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Draw Style */
|
||||
prop = RNA_def_property(srna, "use_volumetric_strokes", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_VOLUMETRIC);
|
||||
RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in "
|
||||
"a volumetric effect");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Use High quality fill */
|
||||
prop = RNA_def_property(srna, "use_hq_fill", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_HQ_FILL);
|
||||
RNA_def_property_ui_text(prop, "High Quality Fill", "Fill strokes using high quality to avoid glitches "
|
||||
"(slower fps during animation play)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Read-only state props (for simpler UI code) */
|
||||
prop = RNA_def_property(srna, "is_stroke_visible", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_GPencilPaletteColor_is_stroke_visible_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Is Stroke Visible", "True when opacity of stroke is set high enough to be visible");
|
||||
|
||||
prop = RNA_def_property(srna, "is_fill_visible", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_GPencilPaletteColor_is_fill_visible_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible");
|
||||
}
|
||||
|
||||
/* palette colors api */
|
||||
static void rna_def_gpencil_palettecolors_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "GPencilPaletteColors");
|
||||
srna = RNA_def_struct(brna, "GPencilPaletteColors", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPDpalette");
|
||||
RNA_def_struct_ui_text(srna, "Palette colors", "Collection of palette colors");
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_GPencilPalette_color_new");
|
||||
RNA_def_function_ui_description(func, "Add a new color to the palette");
|
||||
parm = RNA_def_pointer(func, "color", "GPencilPaletteColor", "", "The newly created color");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_GPencilPalette_color_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a color from the palette");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "color", "GPencilPaletteColor", "", "The color to remove");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GPencilPaletteColor");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_GPencilPalette_active_color_get", "rna_GPencilPalette_active_color_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Active Palette Color", "Current active color");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_GPencilPaletteColor_index_get",
|
||||
"rna_GPencilPaletteColor_index_set",
|
||||
"rna_GPencilPaletteColor_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active color Index", "Index of active palette color");
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_palette(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GPencilPalette", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPDpalette");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Palette", "Collection of related palettes");
|
||||
RNA_def_struct_ui_icon(srna, ICON_COLOR);
|
||||
|
||||
/* Name */
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "info");
|
||||
RNA_def_property_ui_text(prop, "Name", "Palette name");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilPalette_info_set");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Colors */
|
||||
prop = RNA_def_property(srna, "colors", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "colors", NULL);
|
||||
RNA_def_property_struct_type(prop, "GPencilPaletteColor");
|
||||
RNA_def_property_ui_text(prop, "Colors", "Colors of the palette");
|
||||
rna_def_gpencil_palettecolors_api(brna, prop);
|
||||
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_palettes_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "GreasePencilPalettes");
|
||||
srna = RNA_def_struct(brna, "GreasePencilPalettes", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPdata");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Palettes", "Collection of grease pencil palettes");
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_GPencil_palette_new");
|
||||
RNA_def_function_ui_description(func, "Add a new grease pencil palette");
|
||||
parm = RNA_def_string(func, "name", "GPencilPalette", MAX_NAME, "Name", "Name of the palette");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
RNA_def_boolean(func, "set_active", 0, "Set Active", "Activate the newly created palette");
|
||||
parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The newly created palette");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_GPencil_palette_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a grease pencil palette");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The palette to remove");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GPencilPalette");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_palette_get", "rna_GPencil_active_palette_set",
|
||||
NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Active Palette", "Current active palette");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_GPencilPalette_index_get",
|
||||
"rna_GPencilPalette_index_set",
|
||||
"rna_GPencilPalette_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Palette Index", "Index of active palette");
|
||||
}
|
||||
|
||||
static void rna_def_gpencil_data(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -951,6 +1575,13 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Layers", "");
|
||||
rna_def_gpencil_layers_api(brna, prop);
|
||||
|
||||
/* Palettes */
|
||||
prop = RNA_def_property(srna, "palettes", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "palettes", NULL);
|
||||
RNA_def_property_struct_type(prop, "GPencilPalette");
|
||||
RNA_def_property_ui_text(prop, "Palettes", "");
|
||||
rna_def_gpencil_palettes_api(brna, prop);
|
||||
|
||||
/* Animation Data */
|
||||
rna_def_animdata_common(srna);
|
||||
|
||||
@@ -967,6 +1598,12 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
|
||||
"Show ghosts of the frames before and after the current frame, toggle to enable on active layer or disable all");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_stroke_direction", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_DIRECTION);
|
||||
RNA_def_property_ui_text(prop, "Show Direction", "Show stroke drawing direction with a bigger green dot (start) "
|
||||
"and smaller red dot (end) points");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* API Functions */
|
||||
func = RNA_def_function(srna, "clear", "rna_GPencil_clear");
|
||||
RNA_def_function_ui_description(func, "Remove all the grease pencil data");
|
||||
@@ -980,8 +1617,12 @@ void RNA_def_gpencil(BlenderRNA *brna)
|
||||
|
||||
rna_def_gpencil_layer(brna);
|
||||
rna_def_gpencil_frame(brna);
|
||||
rna_def_gpencil_triangle(brna);
|
||||
rna_def_gpencil_stroke(brna);
|
||||
rna_def_gpencil_stroke_point(brna);
|
||||
|
||||
rna_def_gpencil_palette(brna);
|
||||
rna_def_gpencil_palettecolor(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "DNA_linestyle_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
@@ -437,6 +438,7 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_freestyle.h"
|
||||
#include "BKE_gpencil.h"
|
||||
|
||||
#include "ED_info.h"
|
||||
#include "ED_node.h"
|
||||
@@ -449,6 +451,108 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
|
||||
#include "FRS_freestyle.h"
|
||||
#endif
|
||||
|
||||
/* Grease pencil Drawing Brushes */
|
||||
static bGPDbrush *rna_GPencil_brush_new(ToolSettings *ts, const char *name, int setactive)
|
||||
{
|
||||
bGPDbrush *brush = gpencil_brush_addnew(ts, name, setactive != 0);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
static void rna_GPencil_brush_remove(ToolSettings *ts, ReportList *reports, PointerRNA *brush_ptr)
|
||||
{
|
||||
bGPDbrush *brush = brush_ptr->data;
|
||||
if (BLI_findindex(&ts->gp_brushes, brush) == -1) {
|
||||
BKE_report(reports, RPT_ERROR, "Brush not found in grease pencil data");
|
||||
return;
|
||||
}
|
||||
|
||||
gpencil_brush_delete(ts, brush);
|
||||
RNA_POINTER_INVALIDATE(brush_ptr);
|
||||
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static PointerRNA rna_GPencil_active_brush_get(PointerRNA *ptr)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
|
||||
bGPDbrush *brush;
|
||||
|
||||
for (brush = ts->gp_brushes.first; brush; brush = brush->next) {
|
||||
if (brush->flag & GP_BRUSH_ACTIVE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (brush) {
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_GPencilBrush, brush);
|
||||
}
|
||||
|
||||
return rna_pointer_inherit_refine(ptr, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rna_GPencil_active_brush_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
|
||||
bGPDbrush *brush;
|
||||
|
||||
for (brush = ts->gp_brushes.first; brush; brush = brush->next) {
|
||||
if (brush == value.data) {
|
||||
brush->flag |= GP_BRUSH_ACTIVE;
|
||||
}
|
||||
else {
|
||||
brush->flag &= ~GP_BRUSH_ACTIVE;
|
||||
}
|
||||
}
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static int rna_GPencilBrush_index_get(PointerRNA *ptr)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
bGPDbrush *brush = gpencil_brush_getactive(ts);
|
||||
|
||||
return BLI_findindex(&ts->gp_brushes, brush);
|
||||
}
|
||||
|
||||
static void rna_GPencilBrush_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
|
||||
bGPDbrush *brush = BLI_findlink(&ts->gp_brushes, value);
|
||||
|
||||
gpencil_brush_setactive(ts, brush);
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void rna_GPencilBrush_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&ts->gp_brushes) - 1);
|
||||
|
||||
*softmin = *min;
|
||||
*softmax = *max;
|
||||
}
|
||||
|
||||
static void rna_GPencilBrush_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
ToolSettings *ts = (ToolSettings *) ptr->data;
|
||||
bGPDbrush *brush = ptr->data;
|
||||
|
||||
/* copy the new name into the name slot */
|
||||
BLI_strncpy_utf8(brush->info, value, sizeof(brush->info));
|
||||
|
||||
BLI_uniquename(&ts->gp_brushes, brush, DATA_("GP_Brush"), '.', offsetof(bGPDbrush, info), sizeof(brush->info));
|
||||
}
|
||||
|
||||
/* ----------------- end of Grease pencil drawing brushes ------------*/
|
||||
|
||||
static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
ED_space_image_uv_sculpt_update(bmain->wm.first, scene);
|
||||
@@ -1991,6 +2095,202 @@ static int rna_gpu_is_hq_supported_get(PointerRNA *UNUSED(ptr))
|
||||
|
||||
#else
|
||||
|
||||
/* Grease Pencil Drawing Brushes */
|
||||
static void rna_def_gpencil_brush(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "GPencilBrush", NULL);
|
||||
RNA_def_struct_sdna(srna, "bGPDbrush");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Brush", "Collection of brushes being used to control the "
|
||||
"line style of new strokes");
|
||||
RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA);
|
||||
|
||||
/* Name */
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "info");
|
||||
RNA_def_property_ui_text(prop, "Name", "Brush name");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilBrush_name_set");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Line Thickness */
|
||||
prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_int_sdna(prop, NULL, "thickness");
|
||||
RNA_def_property_range(prop, 1, 300);
|
||||
RNA_def_property_ui_range(prop, 1, 10, 1, 0);
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Sensitivity factor for new strokes */
|
||||
prop = RNA_def_property(srna, "pen_sensitivity_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_sensitivity");
|
||||
RNA_def_property_range(prop, 0.1f, 3.0f);
|
||||
RNA_def_property_ui_text(prop, "Sensitivity", "Pressure sensitivity factor for new strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Strength factor for new strokes */
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_strength");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Strength", "Color strength for new strokes (affect alpha factor of color)");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Jitter factor for new strokes */
|
||||
prop = RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_jitter");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Jitter", "Jitter factor for new strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Randomnes factor for sensitivity and strength */
|
||||
prop = RNA_def_property(srna, "random_press", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_random_press");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Randomness", "Randomness factor for pressure and strength in new strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Randomnes factor for subdivision */
|
||||
prop = RNA_def_property(srna, "random_subdiv", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_random_sub");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Random Subdivision", "Randomness factor for new strokes after subdivision");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Angle when brush is full size */
|
||||
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_angle");
|
||||
RNA_def_property_range(prop, 0.0f, M_PI_2);
|
||||
RNA_def_property_ui_text(prop, "Angle", "Angle of drawing when brush has full size");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Factor to change brush size depending of angle */
|
||||
prop = RNA_def_property(srna, "angle_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_angle_factor");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Angle Factor", "Factor to apply when the brush rotate of its full size");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Smoothing factor for new strokes */
|
||||
prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac");
|
||||
RNA_def_property_range(prop, 0.0, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "Smooth", "Amount of smoothing to apply to newly created strokes, to "
|
||||
"reduce jitter/noise");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Iterations of the Smoothing factor */
|
||||
prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl");
|
||||
RNA_def_property_range(prop, 1, 3);
|
||||
RNA_def_property_ui_text(prop, "Iterations", "Number of times to smooth newly created strokes [+ reason/effect "
|
||||
"of using higher values of this property]");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Subdivision level for new strokes */
|
||||
prop = RNA_def_property(srna, "pen_subdivision_steps", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "sublevel");
|
||||
RNA_def_property_range(prop, 0, 3);
|
||||
RNA_def_property_ui_text(prop, "Subdivision Steps", "Number of times to subdivide newly created strokes, for "
|
||||
"less jagged strokes");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Curves for pressure */
|
||||
prop = RNA_def_property(srna, "curve_sensitivity", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "cur_sensitivity");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "curve_strength", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "cur_strength");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_ui_text(prop, "Curve Strength", "Curve used for the strength");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "curve_jitter", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "cur_jitter");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_ui_text(prop, "Curve Jitter", "Curve used for the jitter effect");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
/* Flags */
|
||||
prop = RNA_def_property(srna, "use_pressure", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
RNA_def_property_ui_text(prop, "Use Pressure", "Use tablet pressure");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_STENGTH_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
RNA_def_property_ui_text(prop, "Use Pressure Strength", "Use tablet pressure for color strength");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_JITTER_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
RNA_def_property_ui_text(prop, "Use Pressure Jitter", "Use tablet pressure for jitter");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_random_pressure", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_RANDOM_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_PARTICLES, 0);
|
||||
RNA_def_property_ui_text(prop, "Random Pressure", "Use random value for pressure");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_random_strength", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_RANDOM_STRENGTH);
|
||||
RNA_def_property_ui_icon(prop, ICON_PARTICLES, 0);
|
||||
RNA_def_property_ui_text(prop, "Random Strength", "Use random value for strength");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
|
||||
|
||||
}
|
||||
|
||||
/* Grease Pencil Drawing Brushes API */
|
||||
static void rna_def_gpencil_brushes_api(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "GreasePencilBrushes");
|
||||
srna = RNA_def_struct(brna, "GreasePencilBrushes", NULL);
|
||||
RNA_def_struct_sdna(srna, "ToolSettings");
|
||||
RNA_def_struct_ui_text(srna, "Grease Pencil Brushes", "Collection of grease pencil brushes");
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_GPencil_brush_new");
|
||||
RNA_def_function_ui_description(func, "Add a new grease pencil brush");
|
||||
parm = RNA_def_string(func, "name", "GPencilBrush", MAX_NAME, "Name", "Name of the brush");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created brush to the active brush");
|
||||
parm = RNA_def_pointer(func, "palette", "GPencilBrush", "", "The newly created brush");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_GPencil_brush_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a grease pencil brush");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm = RNA_def_pointer(func, "brush", "GPencilBrush", "", "The brush to remove");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "GPencilBrush");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_brush_get", "rna_GPencil_active_brush_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Active Brush", "Current active brush");
|
||||
|
||||
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_GPencilBrush_index_get",
|
||||
"rna_GPencilBrush_index_set",
|
||||
"rna_GPencilBrush_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active brush Index", "Index of active brush");
|
||||
}
|
||||
|
||||
static void rna_def_transform_orientation(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -2323,6 +2623,13 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "GPencilSculptSettings");
|
||||
RNA_def_property_ui_text(prop, "Grease Pencil Sculpt", "");
|
||||
|
||||
/* Grease Pencil - Drawing brushes */
|
||||
prop = RNA_def_property(srna, "gpencil_brushes", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "gp_brushes", NULL);
|
||||
RNA_def_property_struct_type(prop, "GPencilBrush");
|
||||
RNA_def_property_ui_text(prop, "Grease Pencil Brushes", "Grease Pencil drawing brushes");
|
||||
rna_def_gpencil_brushes_api(brna, prop);
|
||||
|
||||
/* Grease Pencil - 3D View Stroke Placement */
|
||||
prop = RNA_def_property(srna, "gpencil_stroke_placement_view3d", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_v3d_align");
|
||||
@@ -6839,6 +7146,7 @@ void RNA_def_scene(BlenderRNA *brna)
|
||||
/* *** Non-Animated *** */
|
||||
RNA_define_animate_sdna(false);
|
||||
rna_def_tool_settings(brna);
|
||||
rna_def_gpencil_brush(brna);
|
||||
rna_def_unified_paint_settings(brna);
|
||||
rna_def_curve_paint_settings(brna);
|
||||
rna_def_statvis(brna);
|
||||
|
||||
@@ -63,7 +63,8 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = {
|
||||
EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = {
|
||||
{GP_EDITBRUSH_TYPE_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth stroke points"},
|
||||
{GP_EDITBRUSH_TYPE_THICKNESS, "THICKNESS", 0, "Thickness", "Adjust thickness of strokes"},
|
||||
{GP_EDITBRUSH_TYPE_GRAB, "GRAB", 0, "Grab", "Translate the set of points initially within the brush circle"},
|
||||
{ GP_EDITBRUSH_TYPE_STRENGTH, "STRENGTH", 0, "Strength", "Adjust color strength of strokes" },
|
||||
{ GP_EDITBRUSH_TYPE_GRAB, "GRAB", 0, "Grab", "Translate the set of points initially within the brush circle" },
|
||||
{GP_EDITBRUSH_TYPE_PUSH, "PUSH", 0, "Push", "Move points out of the way, as if combing them"},
|
||||
{GP_EDITBRUSH_TYPE_TWIST, "TWIST", 0, "Twist", "Rotate points around the midpoint of the brush"},
|
||||
{GP_EDITBRUSH_TYPE_PINCH, "PINCH", 0, "Pinch", "Pull points towards the midpoint of the brush"},
|
||||
@@ -71,7 +72,7 @@ EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = {
|
||||
//{GP_EDITBRUSH_TYPE_SUBDIVIDE, "SUBDIVIDE", 0, "Subdivide", "Increase point density for higher resolution strokes when zoomed in"},
|
||||
//{GP_EDITBRUSH_TYPE_SIMPLIFY, "SIMPLIFY", 0, "Simplify", "Reduce density of stroke points"},
|
||||
{GP_EDITBRUSH_TYPE_CLONE, "CLONE", 0, "Clone", "Paste copies of the strokes stored on the clipboard"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
{ 0, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
EnumPropertyItem rna_enum_symmetrize_direction_items[] = {
|
||||
@@ -100,6 +101,11 @@ EnumPropertyItem rna_enum_symmetrize_direction_items[] = {
|
||||
|
||||
#include "ED_particle.h"
|
||||
|
||||
static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static EnumPropertyItem particle_edit_disconnected_hair_brush_items[] = {
|
||||
{PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"},
|
||||
{PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"},
|
||||
@@ -1016,6 +1022,27 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
|
||||
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); // FIXME: this needs a custom icon
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "affect_position", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_POSITION);
|
||||
RNA_def_property_ui_text(prop, "Affect position", "The brush affects the position of the point");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "affect_strength", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_STRENGTH);
|
||||
RNA_def_property_ui_text(prop, "Affect strength", "The brush affects the color strength of the point");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "affect_thickness", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_THICKNESS);
|
||||
RNA_def_property_ui_text(prop, "Affect thickness", "The brush affects the thickness of the point");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "selection_alpha", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "alpha");
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Alpha", "Alpha value for selected vertices");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_GPencil_update");
|
||||
|
||||
/* brush */
|
||||
srna = RNA_def_struct(brna, "GPencilSculptBrush", NULL);
|
||||
RNA_def_struct_sdna(srna, "GP_EditBrush_Data");
|
||||
|
||||
@@ -238,6 +238,9 @@ void RE_render_result_rect_from_ibuf(
|
||||
struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name);
|
||||
float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, int passtype, const char *viewname);
|
||||
|
||||
/* add passes for grease pencil */
|
||||
struct RenderPass *RE_create_gp_pass(struct RenderResult *rr, const char *layername, const char *viewname);
|
||||
|
||||
/* obligatory initialize call, disprect is optional */
|
||||
void RE_InitState(struct Render *re, struct Render *source, struct RenderData *rd,
|
||||
struct SceneRenderLayer *srl,
|
||||
|
||||
@@ -83,6 +83,9 @@ void render_result_save_empty_result_tiles(struct Render *re);
|
||||
void render_result_exr_file_begin(struct Render *re);
|
||||
void render_result_exr_file_end(struct Render *re);
|
||||
|
||||
/* render pass wrapper for gpencil */
|
||||
struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, int passtype, const char *viewname);
|
||||
|
||||
void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, const char *viewname);
|
||||
|
||||
void render_result_exr_file_path(struct Scene *scene, const char *layname, int sample, char *filepath);
|
||||
|
||||
@@ -4018,3 +4018,31 @@ RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const c
|
||||
}
|
||||
return rp;
|
||||
}
|
||||
|
||||
/* create a renderlayer and renderpass for grease pencil layer */
|
||||
RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname)
|
||||
{
|
||||
RenderLayer *rl = BLI_findstring(&rr->layers, layername, offsetof(RenderLayer, name));
|
||||
/* only create render layer if not exist */
|
||||
if (!rl) {
|
||||
rl = MEM_callocN(sizeof(RenderLayer), layername);
|
||||
BLI_addtail(&rr->layers, rl);
|
||||
BLI_strncpy(rl->name, layername, sizeof(rl->name));
|
||||
rl->lay = 0;
|
||||
rl->layflag = SCE_LAY_SOLID;
|
||||
rl->passflag = SCE_PASS_COMBINED;
|
||||
rl->rectx = rr->rectx;
|
||||
rl->recty = rr->recty;
|
||||
}
|
||||
|
||||
/* clear previous pass if exist or the new image will be over previous one*/
|
||||
RenderPass *rp = RE_pass_find_by_type(rl, SCE_PASS_COMBINED, viewname);
|
||||
if (rp) {
|
||||
if (rp->rect) {
|
||||
MEM_freeN(rp->rect);
|
||||
}
|
||||
BLI_freelinkN(&rl->passes, rp);
|
||||
}
|
||||
/* create a totally new pass */
|
||||
return gp_add_pass(rr, rl, 4, SCE_PASS_COMBINED, viewname);
|
||||
}
|
||||
|
||||
@@ -540,6 +540,11 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
|
||||
|
||||
return rpass;
|
||||
}
|
||||
/* wrapper called from render_opengl */
|
||||
RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
|
||||
{
|
||||
return render_layer_add_pass(rr, rl, channels, passtype, viewname);
|
||||
}
|
||||
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
const char *RE_debug_pass_name_get(int debug_type)
|
||||
|
||||
@@ -111,6 +111,7 @@ struct bConstraint;
|
||||
struct bConstraintOb;
|
||||
struct bConstraintTarget;
|
||||
struct bContextDataResult;
|
||||
struct bGPDlayer;
|
||||
struct bNode;
|
||||
struct bNodeType;
|
||||
struct bNodeSocket;
|
||||
@@ -153,6 +154,7 @@ struct wmWindowManager;
|
||||
#include "../blender/editors/include/ED_clip.h"
|
||||
#include "../blender/editors/include/ED_curve.h"
|
||||
#include "../blender/editors/include/ED_fileselect.h"
|
||||
#include "../blender/editors/include/ED_gpencil.h"
|
||||
#include "../blender/editors/include/ED_image.h"
|
||||
#include "../blender/editors/include/ED_info.h"
|
||||
#include "../blender/editors/include/ED_keyframes_edit.h"
|
||||
@@ -350,6 +352,7 @@ void *ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const stru
|
||||
void *ED_region_draw_cb_customdata(void *handle) RET_ZERO /* XXX This one looks wrong also */
|
||||
void ED_region_draw_cb_exit(struct ARegionType *art, void *handle) RET_NONE
|
||||
void ED_area_headerprint(struct ScrArea *sa, const char *str) RET_NONE
|
||||
void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]) RET_NONE
|
||||
void UI_view2d_region_to_view(struct View2D *v2d, float x, float y, float *viewx, float *viewy) RET_NONE
|
||||
bool UI_view2d_view_to_region_clip(struct View2D *v2d, float x, float y, int *regionx, int *regiony) RET_ZERO
|
||||
void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, int *regionx, int *region_y) RET_NONE
|
||||
|
||||
Reference in New Issue
Block a user