*/}}

ournodes.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Our Paint: A light weight GPU powered painting program.
  3. * Copyright (C) 2022-2023 Wu Yiming
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "ourpaint.h"
  19. extern LA MAIN;
  20. extern tnsMain* T;
  21. extern OurPaint *Our;
  22. laBaseNodeType OUR_IDN_BRUSH_SETTINGS;
  23. laBaseNodeType OUR_IDN_BRUSH_OUTPUTS;
  24. laBaseNodeType OUR_IDN_BRUSH_DEVICE;
  25. laPropContainer* OUR_PC_IDN_BRUSH_SETTINGS;
  26. laPropContainer* OUR_PC_IDN_BRUSH_OUTPUTS;
  27. laPropContainer* OUR_PC_IDN_BRUSH_DEVICE;
  28. void IDN_BrushSettingsInit(OurBrushSettingsNode* n, int NoCreate){
  29. if(!NoCreate){
  30. n->CanvasScale=laCreateOutSocket(n,"Canvas Scale",LA_PROP_FLOAT);
  31. n->Size=laCreateOutSocket(n,"SIZE",LA_PROP_FLOAT);
  32. n->Transparency=laCreateOutSocket(n,"TRANSP",LA_PROP_FLOAT);
  33. n->Hardness=laCreateOutSocket(n,"HARD",LA_PROP_FLOAT);
  34. n->Smudge=laCreateOutSocket(n,"SMUDGE",LA_PROP_FLOAT);
  35. n->SmudgeLength=laCreateOutSocket(n,"LEN",LA_PROP_FLOAT);
  36. n->DabsPerSize=laCreateOutSocket(n,"Dabs Per Size",LA_PROP_FLOAT);
  37. n->Slender=laCreateOutSocket(n,"SLENDER",LA_PROP_FLOAT);
  38. n->Angle=laCreateOutSocket(n,"ANGLE",LA_PROP_FLOAT);
  39. n->Color=laCreateOutSocket(n,"COLOR",LA_PROP_FLOAT|LA_PROP_ARRAY);
  40. strSafeSet(&n->Base.Name, "Brush Settings");
  41. }
  42. if(!n->Iteration) n->Iteration=laCreateOutSocket(n,"ITER",LA_PROP_INT);
  43. if(!n->Custom1) n->Custom1=laCreateOutSocket(n,"C1",LA_PROP_FLOAT);
  44. if(!n->Custom2) n->Custom2=laCreateOutSocket(n,"C2",LA_PROP_FLOAT);
  45. if(!n->Gunkyness) n->Gunkyness=laCreateOutSocket(n,"GUNKY",LA_PROP_FLOAT);
  46. if(!n->Force) n->Force=laCreateOutSocket(n,"FORCE",LA_PROP_FLOAT);
  47. if(!n->Accumulation) n->Accumulation=laCreateOutSocket(n,"ACCUM",LA_PROP_FLOAT);
  48. n->CanvasScale->Data=&n->rCanvasScale;
  49. n->Size->Data=&n->rSize;
  50. n->Transparency->Data=&n->rTransparency;
  51. n->Hardness->Data=&n->rHardness;
  52. n->Smudge->Data=&n->rSmudge;
  53. n->SmudgeLength->Data=&n->rSmudgeLength;
  54. n->DabsPerSize->Data=&n->rDabsPerSize;
  55. n->Slender->Data=&n->rSlender;
  56. n->Angle->Data=&n->rAngle;
  57. n->Color->Data=Our->CurrentColor; n->Color->ArrLen=3;
  58. n->Gunkyness->Data=&n->rGunkyness;
  59. n->Accumulation->Data=&n->rAccumulation;
  60. n->Force->Data=&n->rForce;
  61. n->Iteration->Data=&n->rIteration;
  62. n->Custom1->Data=&n->rCustom1;
  63. n->Custom2->Data=&n->rCustom2;
  64. }
  65. void IDN_BrushSettingsDestroy(OurBrushSettingsNode* n){
  66. laDestroyOutSocket(n->Size); laDestroyOutSocket(n->Transparency); laDestroyOutSocket(n->Hardness); laDestroyOutSocket(n->Smudge);
  67. laDestroyOutSocket(n->SmudgeLength); laDestroyOutSocket(n->DabsPerSize); laDestroyOutSocket(n->Slender); laDestroyOutSocket(n->Angle);
  68. laDestroyOutSocket(n->CanvasScale); laDestroyOutSocket(n->Iteration); laDestroyOutSocket(n->Custom1); laDestroyOutSocket(n->Custom2);
  69. laDestroyOutSocket(n->Gunkyness); laDestroyOutSocket(n->Force); laDestroyOutSocket(n->Accumulation);
  70. strSafeDestroy(&n->Base.Name);
  71. }
  72. int IDN_BrushSettingsVisit(OurBrushSettingsNode* n, laNodeVisitInfo* vi){
  73. LA_GUARD_THIS_NODE(n,vi); LA_ADD_THIS_NODE(n,vi);
  74. return LA_DAG_FLAG_PERM;
  75. }
  76. int IDN_BrushSettingsEval(OurBrushSettingsNode* n){
  77. if(!Our->CurrentBrush){ return 0; } // unlikely;
  78. n->rCanvasScale = Our->CurrentScale;
  79. n->rSize = OUR_BRUSH_ACTUAL_SIZE(Our->CurrentBrush);
  80. n->rTransparency = Our->CurrentBrush->Transparency;
  81. n->rHardness = Our->CurrentBrush->Hardness;
  82. n->rSmudge = Our->CurrentBrush->Smudge;
  83. n->rSmudgeLength = Our->CurrentBrush->SmudgeResampleLength;
  84. n->rDabsPerSize = Our->CurrentBrush->DabsPerSize;
  85. n->rSlender = Our->CurrentBrush->Slender;
  86. n->rAngle = Our->CurrentBrush->Angle;
  87. n->rGunkyness = Our->CurrentBrush->Gunkyness;
  88. n->rAccumulation = Our->CurrentBrush->Accumulation;
  89. n->rForce = Our->CurrentBrush->Force;
  90. n->rIteration = Our->CurrentBrush->Iteration;
  91. n->rCustom1 = Our->CurrentBrush->Custom1;
  92. n->rCustom2 = Our->CurrentBrush->Custom2;
  93. return 1;
  94. }
  95. void IDN_BrushSettingsCopy(OurBrushSettingsNode* new, OurBrushSettingsNode* old, int DoRematch){
  96. if(DoRematch){ return;}
  97. LA_IDN_OLD_DUPL(Angle) LA_IDN_OLD_DUPL(CanvasScale)
  98. LA_IDN_OLD_DUPL(Color) LA_IDN_OLD_DUPL(Custom1)
  99. LA_IDN_OLD_DUPL(Custom2) LA_IDN_OLD_DUPL(DabsPerSize)
  100. LA_IDN_OLD_DUPL(Hardness) LA_IDN_OLD_DUPL(Iteration)
  101. LA_IDN_OLD_DUPL(Size) LA_IDN_OLD_DUPL(Slender)
  102. LA_IDN_OLD_DUPL(Smudge) LA_IDN_OLD_DUPL(SmudgeLength)
  103. LA_IDN_OLD_DUPL(Transparency)LA_IDN_OLD_DUPL(Gunkyness)
  104. LA_IDN_OLD_DUPL(Force) LA_IDN_OLD_DUPL(Accumulation)
  105. }
  106. void ui_BrushSettingsNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  107. laColumn* c=laFirstColumn(uil); OurBrushSettingsNode*n=This->EndInstance;
  108. laUiItem* b,*u;
  109. LA_BASE_NODE_HEADER(uil,c,This);
  110. b=laBeginRow(uil,c,0,0);
  111. laShowSeparator(uil,c)->Expand=1;
  112. laShowNodeSocket(uil,c,This,"size",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  113. laShowNodeSocket(uil,c,This,"transparency",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  114. laShowNodeSocket(uil,c,This,"hardness",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  115. laShowNodeSocket(uil,c,This,"slender",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  116. laShowNodeSocket(uil,c,This,"angle",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  117. laShowNodeSocket(uil,c,This,"color",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  118. laEndRow(uil,b);
  119. b=laBeginRow(uil,c,0,0);
  120. laShowSeparator(uil,c)->Expand=1;
  121. laShowNodeSocket(uil,c,This,"smudge_length",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  122. laShowNodeSocket(uil,c,This,"smudge",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  123. laEndRow(uil,b);
  124. b=laBeginRow(uil,c,0,0);
  125. laShowSeparator(uil,c)->Expand=1;
  126. laShowNodeSocket(uil,c,This,"gunkyness",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  127. laShowNodeSocket(uil,c,This,"force",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  128. laShowNodeSocket(uil,c,This,"accumulation",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  129. laEndRow(uil,b);
  130. b=laBeginRow(uil,c,0,0); u=laShowLabel(uil,c,"Canvas Scale",0,0);u->Flags|=LA_TEXT_ALIGN_RIGHT; u->Expand=1; laShowNodeSocket(uil,c,This,"canvas_scale",0);
  131. u=laShowLabel(uil,c,"Dabs Per Size",0,0);u->Flags|=LA_TEXT_ALIGN_RIGHT; u->Expand=1; laShowNodeSocket(uil,c,This,"dabs_per_size",0); laEndRow(uil,b);
  132. b=laBeginRow(uil,c,0,0);
  133. laShowSeparator(uil,c)->Expand=1; laShowNodeSocket(uil,c,This,"iteration",0)->Flags|=LA_UI_SOCKET_LABEL_W;
  134. laEndRow(uil,b);
  135. b=laBeginRow(uil,c,0,0); u=laShowItem(uil,c,0,"our.tools.current_brush.c1_name");u->Flags|=LA_UI_FLAGS_PLAIN|LA_TEXT_ALIGN_RIGHT; u->Expand=1;
  136. laShowNodeSocket(uil,c,This,"c1",0); laEndRow(uil,b);
  137. b=laBeginRow(uil,c,0,0); u=laShowItem(uil,c,0,"our.tools.current_brush.c2_name");u->Flags|=LA_UI_FLAGS_PLAIN|LA_TEXT_ALIGN_RIGHT; u->Expand=1;
  138. laShowNodeSocket(uil,c,This,"c2",0); laEndRow(uil,b);
  139. }
  140. void IDN_BrushOutputsInit(OurBrushOutputsNode* n, int NoCreate){
  141. if(!NoCreate){
  142. n->Offset=laCreateInSocket("OFFSET",LA_PROP_FLOAT);
  143. n->Size=laCreateInSocket("SIZE",LA_PROP_FLOAT);
  144. n->Transparency=laCreateInSocket("TRANSP",LA_PROP_FLOAT);
  145. n->Hardness=laCreateInSocket("HRAD",LA_PROP_FLOAT);
  146. n->Smudge=laCreateInSocket("SMUDGE",LA_PROP_FLOAT);
  147. n->SmudgeLength=laCreateInSocket("LENGTH",LA_PROP_FLOAT);
  148. n->DabsPerSize=laCreateInSocket("Dabs Per Size",LA_PROP_FLOAT);
  149. n->Slender=laCreateInSocket("SLENDER",LA_PROP_FLOAT);
  150. n->Angle=laCreateInSocket("ANGLE",LA_PROP_FLOAT);
  151. n->Color=laCreateInSocket("COLOR",LA_PROP_FLOAT);
  152. }
  153. if(!n->Repeats) n->Repeats=laCreateInSocket("REPEATS",LA_PROP_INT);
  154. if(!n->Discard) n->Discard=laCreateInSocket("DISCARD",LA_PROP_INT);
  155. if(!n->Gunkyness) n->Gunkyness=laCreateInSocket("GUNKY",LA_PROP_FLOAT);
  156. if(!n->Force) n->Force=laCreateInSocket("FORCE",LA_PROP_FLOAT);
  157. if(!n->Accumulation) n->Accumulation=laCreateInSocket("ACCUM",LA_PROP_FLOAT);
  158. strSafeSet(&n->Base.Name, "Brush Outputs");
  159. }
  160. void IDN_BrushOutputsDestroy(OurBrushOutputsNode* n){
  161. laDestroyInSocket(n->Offset);
  162. laDestroyInSocket(n->Size); laDestroyInSocket(n->Transparency); laDestroyInSocket(n->Hardness); laDestroyInSocket(n->Smudge);
  163. laDestroyInSocket(n->SmudgeLength); laDestroyInSocket(n->DabsPerSize); laDestroyInSocket(n->Slender); laDestroyInSocket(n->Angle);
  164. laDestroyInSocket(n->Color); laDestroyInSocket(n->Repeats); laDestroyInSocket(n->Discard);
  165. laDestroyInSocket(n->Gunkyness); laDestroyInSocket(n->Force); laDestroyInSocket(n->Accumulation);
  166. strSafeDestroy(&n->Base.Name);
  167. }
  168. int IDN_BrushOutputsVisit(OurBrushOutputsNode* n, laNodeVisitInfo* vi){
  169. LA_GUARD_THIS_NODE(n,vi);
  170. #define BRUSH_OUT_VISIT(a) \
  171. if(LA_SRC_AND_PARENT(n->a)){ laBaseNode*bn=n->a->Source->Parent; LA_VISIT_NODE(bn,vi); }
  172. BRUSH_OUT_VISIT(Offset) BRUSH_OUT_VISIT(Size) BRUSH_OUT_VISIT(Transparency)
  173. BRUSH_OUT_VISIT(Hardness) BRUSH_OUT_VISIT(Smudge) BRUSH_OUT_VISIT(SmudgeLength)
  174. BRUSH_OUT_VISIT(DabsPerSize) BRUSH_OUT_VISIT(Slender) BRUSH_OUT_VISIT(Angle)
  175. BRUSH_OUT_VISIT(Color) BRUSH_OUT_VISIT(Repeats) BRUSH_OUT_VISIT(Discard)
  176. BRUSH_OUT_VISIT(Gunkyness) BRUSH_OUT_VISIT(Force) BRUSH_OUT_VISIT(Accumulation)
  177. #undef BRUSH_OUT_VISIT
  178. LA_ADD_THIS_NODE(n,vi);
  179. return LA_DAG_FLAG_PERM;
  180. }
  181. int IDN_BrushOutputsEval(OurBrushOutputsNode* n){
  182. if(!Our->CurrentBrush) return 0;
  183. #define BRUSH_OUT_EVAL(a) \
  184. if(LA_SRC_AND_PARENT(n->a)){ \
  185. if(n->a->Source->DataType&LA_PROP_INT){ Our->CurrentBrush->Eval##a=*((int*)n->a->Source->Data); } \
  186. if(n->a->Source->DataType&LA_PROP_FLOAT){ Our->CurrentBrush->Eval##a=*((real*)n->a->Source->Data); } \
  187. }
  188. if(LA_SRC_AND_PARENT(n->Offset) && (n->Offset->Source->DataType&LA_PROP_FLOAT|LA_PROP_ARRAY) && n->Offset->Source->ArrLen>=2){
  189. Our->CurrentBrush->EvalOffset[0]=((real*)n->Offset->Source->Data)[0];
  190. Our->CurrentBrush->EvalOffset[1]=((real*)n->Offset->Source->Data)[1];
  191. }
  192. if(LA_SRC_AND_PARENT(n->Color) && (n->Color->Source->DataType&LA_PROP_FLOAT|LA_PROP_ARRAY) && n->Color->Source->ArrLen>=3){
  193. Our->CurrentBrush->EvalColor[0]=((real*)n->Color->Source->Data)[0];
  194. Our->CurrentBrush->EvalColor[1]=((real*)n->Color->Source->Data)[1];
  195. Our->CurrentBrush->EvalColor[2]=((real*)n->Color->Source->Data)[2];
  196. }
  197. BRUSH_OUT_EVAL(Size)
  198. BRUSH_OUT_EVAL(Transparency)
  199. BRUSH_OUT_EVAL(Hardness)
  200. BRUSH_OUT_EVAL(Smudge)
  201. BRUSH_OUT_EVAL(SmudgeLength)
  202. BRUSH_OUT_EVAL(DabsPerSize)
  203. BRUSH_OUT_EVAL(Slender)
  204. BRUSH_OUT_EVAL(Angle)
  205. BRUSH_OUT_EVAL(Gunkyness)
  206. BRUSH_OUT_EVAL(Force)
  207. BRUSH_OUT_EVAL(Accumulation)
  208. BRUSH_OUT_EVAL(Repeats)
  209. BRUSH_OUT_EVAL(Discard)
  210. #undef BRUSH_OUT_EVAL
  211. return 1;
  212. }
  213. void IDN_BrushOutputsCopy(OurBrushOutputsNode* new, OurBrushOutputsNode* old, int DoRematch){
  214. if(DoRematch){
  215. LA_IDN_NEW_LINK(Offset) LA_IDN_NEW_LINK(Size) LA_IDN_NEW_LINK(Transparency) LA_IDN_NEW_LINK(Hardness)
  216. LA_IDN_NEW_LINK(Smudge) LA_IDN_NEW_LINK(SmudgeLength) LA_IDN_NEW_LINK(DabsPerSize) LA_IDN_NEW_LINK(Slender)
  217. LA_IDN_NEW_LINK(Angle) LA_IDN_NEW_LINK(Color) LA_IDN_NEW_LINK(Repeats) LA_IDN_NEW_LINK(Discard)
  218. LA_IDN_NEW_LINK(Gunkyness) LA_IDN_NEW_LINK(Force) LA_IDN_NEW_LINK(Accumulation)
  219. return;
  220. }
  221. return;
  222. }
  223. void ui_BrushOutputsNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  224. laColumn* c=laFirstColumn(uil); OurBrushOutputsNode*n=This->EndInstance;
  225. laUiItem* b,*u;
  226. LA_BASE_NODE_HEADER(uil,c,This);
  227. b=laBeginRow(uil,c,0,0);
  228. laShowNodeSocket(uil,c,This,"offset",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  229. laShowNodeSocket(uil,c,This,"size",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  230. laShowNodeSocket(uil,c,This,"transparency",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  231. laShowNodeSocket(uil,c,This,"hardness",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  232. laShowNodeSocket(uil,c,This,"slender",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  233. laShowNodeSocket(uil,c,This,"angle",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  234. laShowNodeSocket(uil,c,This,"color",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  235. laEndRow(uil,b);
  236. b=laBeginRow(uil,c,0,0);
  237. laShowNodeSocket(uil,c,This,"smudge",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  238. laShowNodeSocket(uil,c,This,"smudge_length",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  239. laEndRow(uil,b);
  240. b=laBeginRow(uil,c,0,0);
  241. laShowNodeSocket(uil,c,This,"gunkyness",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  242. laShowNodeSocket(uil,c,This,"force",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  243. laShowNodeSocket(uil,c,This,"accumulation",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  244. laEndRow(uil,b);
  245. b=laBeginRow(uil,c,0,0); laShowNodeSocket(uil,c,This,"dabs_per_size",0); laShowLabel(uil,c,"Dabs Per Size",0,0); laEndRow(uil,b);
  246. b=laBeginRow(uil,c,0,0);
  247. laShowNodeSocket(uil,c,This,"repeats",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  248. laShowNodeSocket(uil,c,This,"discard",0)->Flags|=LA_UI_SOCKET_LABEL_E;
  249. laEndRow(uil,b);
  250. }
  251. void IDN_BrushDeviceInit(OurBrushDeviceNode* n, int NoCreate){
  252. if(!NoCreate){
  253. n->Pressure=laCreateOutSocket(n,"PRESSURE",LA_PROP_FLOAT);
  254. n->Tilt=laCreateOutSocket(n,"TILT",LA_PROP_FLOAT|LA_PROP_ARRAY);
  255. n->IsEraser=laCreateOutSocket(n,"ERASER",LA_PROP_INT);
  256. n->Position=laCreateOutSocket(n,"POS",LA_PROP_FLOAT|LA_PROP_ARRAY);
  257. n->Speed=laCreateOutSocket(n,"SPD",LA_PROP_FLOAT);
  258. n->Angle=laCreateOutSocket(n,"ANGLE",LA_PROP_FLOAT);
  259. n->Length=laCreateOutSocket(n,"LENGTH",LA_PROP_FLOAT);
  260. n->LengthAccum=laCreateOutSocket(n,"ACUM",LA_PROP_FLOAT);
  261. strSafeSet(&n->Base.Name, "Brush Device");
  262. }
  263. if(!n->Twist){ n->Twist=laCreateOutSocket(n,"TWIST",LA_PROP_FLOAT); }
  264. n->Pressure->Data=&n->rPressure;
  265. n->Tilt->Data=n->rTilt; n->Tilt->ArrLen=2;
  266. n->Twist->Data=&n->rTwist;
  267. n->IsEraser->Data=&n->rIsEraser;
  268. n->Position->Data=n->rPosition; n->Position->ArrLen=2;
  269. n->Speed->Data=&n->rSpeed;
  270. n->Angle->Data=&n->rAngle;
  271. n->Length->Data=&n->rLength;
  272. n->LengthAccum->Data=&n->rLengthAccum;
  273. }
  274. void IDN_BrushDeviceDestroy(OurBrushDeviceNode* n){
  275. laDestroyOutSocket(n->Pressure); laDestroyOutSocket(n->Tilt); laDestroyOutSocket(n->Position); laDestroyOutSocket(n->IsEraser); laDestroyOutSocket(n->Speed);
  276. laDestroyOutSocket(n->Angle); laDestroyOutSocket(n->Length); laDestroyOutSocket(n->LengthAccum); laDestroyOutSocket(n->Twist);
  277. strSafeDestroy(&n->Base.Name);
  278. }
  279. int IDN_BrushDeviceVisit(OurBrushDeviceNode* n, laNodeVisitInfo* vi){
  280. LA_GUARD_THIS_NODE(n,vi); LA_ADD_THIS_NODE(n,vi);
  281. return LA_DAG_FLAG_PERM;
  282. }
  283. int IDN_BrushDeviceEval(OurBrushDeviceNode* n){
  284. if(!Our->CurrentBrush){ return 0; } // unlikely;
  285. tnsVectorSet2v(n->rPosition, Our->CurrentBrush->EvalPosition);
  286. tnsVectorSet2v(n->rTilt, Our->CurrentBrush->EvalTilt);
  287. n->rAngle=Our->CurrentBrush->EvalStrokeAngle;
  288. n->rIsEraser = Our->CurrentBrush->EvalIsEraser;
  289. n->rPressure = Our->CurrentBrush->EvalPressure;
  290. n->rTwist = Our->CurrentBrush->EvalTwist;
  291. n->rSpeed = Our->CurrentBrush->EvalSpeed;
  292. n->rLength = Our->CurrentBrush->EvalStrokeLength;
  293. n->rLengthAccum = Our->CurrentBrush->EvalStrokeLengthAccum;
  294. return 1;
  295. }
  296. void IDN_BrushDeviceCopy(OurBrushDeviceNode* new, OurBrushDeviceNode* old, int DoRematch){
  297. if(DoRematch){ return;}
  298. LA_IDN_OLD_DUPL(Pressure) LA_IDN_OLD_DUPL(Tilt) LA_IDN_OLD_DUPL(Position) LA_IDN_OLD_DUPL(Twist)
  299. LA_IDN_OLD_DUPL(IsEraser) LA_IDN_OLD_DUPL(Speed) LA_IDN_OLD_DUPL(Angle)
  300. LA_IDN_OLD_DUPL(Length) LA_IDN_OLD_DUPL(LengthAccum)
  301. }
  302. void ui_BrushDeviceNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
  303. laColumn* c=laFirstColumn(uil); OurBrushDeviceNode*n=This->EndInstance;
  304. laUiItem* b,*u;
  305. LA_BASE_NODE_HEADER(uil,c,This);
  306. b=laBeginRow(uil,c,0,0);
  307. laShowSeparator(uil,c)->Expand=1;
  308. laShowNodeSocket(uil,c,This,"position",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  309. laShowNodeSocket(uil,c,This,"speed",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  310. laShowNodeSocket(uil,c,This,"angle",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  311. laShowNodeSocket(uil,c,This,"pressure",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  312. laShowNodeSocket(uil,c,This,"tilt",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  313. laShowNodeSocket(uil,c,This,"twist",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  314. laShowNodeSocket(uil,c,This,"is_eraser",0)->Flags|=LA_UI_SOCKET_LABEL_N;
  315. laEndRow(uil,b);
  316. b=laBeginRow(uil,c,0,0); laShowSeparator(uil,c)->Expand=1;
  317. laShowNodeSocket(uil,c,This,"length_accum",0)->Flags|=LA_UI_SOCKET_LABEL_W; laShowNodeSocket(uil,c,This,"length",0)->Flags|=LA_UI_SOCKET_LABEL_W; laEndRow(uil,b);
  318. }
  319. int ourEvalBrush(){
  320. return Our->CurrentBrush?laRunPage(Our->CurrentBrush->Rack, 1):0;
  321. }
  322. int ourRebuildBrushEval(){
  323. return Our->CurrentBrush?laRebuildPageEval(Our->CurrentBrush->Rack):0;
  324. }
  325. void ourRegisterNodes(){
  326. laPropContainer *pc; laProp *p;
  327. laOperatorType *at;
  328. laEnumProp *ep;
  329. pc=laAddPropertyContainer("our_node_brush_settings", "Brush Settings", "Brush settings node to read from",0,ui_BrushSettingsNode,sizeof(OurBrushSettingsNode),lapost_Node,0,1);
  330. OUR_PC_IDN_BRUSH_SETTINGS=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  331. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  332. laAddSubGroup(pc,"canvas_scale", "Canvas scale","Canvas scale","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,CanvasScale),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  333. laAddSubGroup(pc,"size", "Size","Size","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Size),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  334. laAddSubGroup(pc,"transparency", "Transparency","Transparency","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Transparency),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  335. laAddSubGroup(pc,"hardness", "Hardness","Hardness","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Hardness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  336. laAddSubGroup(pc,"smudge", "Smudge","Smudge","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Smudge),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  337. laAddSubGroup(pc,"smudge_length", "Smudge Length","Smudge length","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,SmudgeLength),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  338. laAddSubGroup(pc,"dabs_per_size", "Dabs Per Size","Dabs per size","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,DabsPerSize),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  339. laAddSubGroup(pc,"slender", "Slender","Slender","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Slender),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  340. laAddSubGroup(pc,"angle", "Angle","Angle","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Angle),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  341. laAddSubGroup(pc,"color", "Color","Color","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Color),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  342. laAddSubGroup(pc,"gunkyness", "Gunkyness","Gunkyness","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Gunkyness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  343. laAddSubGroup(pc,"force", "Force","Force","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Force),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  344. laAddSubGroup(pc,"accumulation", "Accumulation","Accumulation","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Accumulation),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  345. laAddSubGroup(pc,"iteration", "Iteration","Iteration","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Iteration),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  346. laAddSubGroup(pc,"c1", "C1","Custom 1","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Custom1),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  347. laAddSubGroup(pc,"c2", "C2","Custom 2","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Custom2),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  348. pc=laAddPropertyContainer("our_node_brush_outputs", "Brush Outputs", "Brush outputs to draw actual dabs",0,ui_BrushOutputsNode,sizeof(OurBrushOutputsNode),lapost_Node,0,1);
  349. OUR_PC_IDN_BRUSH_OUTPUTS=pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  350. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  351. laAddSubGroup(pc,"offset", "Offset","Offset","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Offset),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  352. laAddSubGroup(pc,"size", "Size","Size","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Size),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  353. laAddSubGroup(pc,"transparency", "Transparency","Transparency","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Transparency),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  354. laAddSubGroup(pc,"hardness", "Hardness","Hardness","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Hardness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  355. laAddSubGroup(pc,"smudge", "Smudge","Smudge","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Smudge),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  356. laAddSubGroup(pc,"smudge_length", "Smudge Length","Smudge length","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,SmudgeLength),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  357. laAddSubGroup(pc,"dabs_per_size", "Dabs Per Size","Dabs per size","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,DabsPerSize),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  358. laAddSubGroup(pc,"slender", "Slender","Slender","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Slender),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  359. laAddSubGroup(pc,"angle", "Angle","Angle","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Angle),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  360. laAddSubGroup(pc,"gunkyness", "Gunkyness","Gunkyness","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Gunkyness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  361. laAddSubGroup(pc,"force", "Force","Force","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Force),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  362. laAddSubGroup(pc,"accumulation", "Accumulation","Accumulation","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Accumulation),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  363. laAddSubGroup(pc,"color", "Color","Color","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Color),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  364. laAddSubGroup(pc,"repeats", "Repeats","Repeats","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Repeats),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  365. laAddSubGroup(pc,"discard", "Discard","Discard","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Discard),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  366. pc=laAddPropertyContainer("our_node_brush_device", "Brush Device", "Brush device input",0,ui_BrushDeviceNode,sizeof(OurBrushDeviceNode),lapost_Node,0,1);
  367. OUR_PC_IDN_BRUSH_DEVICE =pc; laPropContainerExtraFunctions(pc,0,0,0,0,laui_DefaultNodeOperationsPropUiDefine);
  368. laAddSubGroup(pc,"base","Base","Base node","la_base_node",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
  369. laAddSubGroup(pc,"pressure","Pressure","Pressure of the input","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Pressure),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  370. laAddSubGroup(pc,"tilt", "Tilt","Pen tilt vector","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Tilt),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  371. laAddSubGroup(pc,"twist", "Twist","Pen twist angle","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Twist),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  372. laAddSubGroup(pc,"is_eraser", "Is Eraser","Input event is from an eraser","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,IsEraser),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  373. laAddSubGroup(pc,"position", "Dab position","Interpolated dab position","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Position),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  374. laAddSubGroup(pc,"speed","Speed","Speed on the canvas","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Speed),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  375. laAddSubGroup(pc,"angle","Angle","Direction of the brush","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Angle),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  376. laAddSubGroup(pc,"length","Length","Length of this brush stroke","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,Length),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  377. laAddSubGroup(pc,"length_accum","Accumulated Length","Accumulated stroke length","la_out_socket",0,0,0,offsetof(OurBrushDeviceNode,LengthAccum),0,0,0,0,0,0,0,LA_UDF_SINGLE);
  378. LA_IDN_REGISTER("Brush Settings",U'⚙',OUR_IDN_BRUSH_SETTINGS,OUR_PC_IDN_BRUSH_SETTINGS, IDN_BrushSettings, OurBrushSettingsNode);
  379. LA_IDN_REGISTER("Brush Outputs",U'🌈',OUR_IDN_BRUSH_OUTPUTS,OUR_PC_IDN_BRUSH_OUTPUTS, IDN_BrushOutputs, OurBrushOutputsNode);
  380. LA_IDN_REGISTER("Brush Device",U'🖌',OUR_IDN_BRUSH_DEVICE,OUR_PC_IDN_BRUSH_DEVICE, IDN_BrushDevice, OurBrushDeviceNode);
  381. //laNodeCategory* nc=laEnsureNodeCategory("Our Paint",0,LA_RACK_TYPE_DRIVER);
  382. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_DRIVER, &OUR_IDN_BRUSH_OUTPUTS,0LL);
  383. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_INPUT, &OUR_IDN_BRUSH_DEVICE, 0LL);
  384. laNodeCategoryAddNodeTypes(LA_NODE_CATEGORY_INPUT, &OUR_IDN_BRUSH_SETTINGS, 0LL);
  385. }