BEZIER.C 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271
  1. /****************************************************************************
  2. * bezier.c
  3. *
  4. * This module implements the code for Bezier bicubic patch shapes
  5. *
  6. * This file was written by Alexander Enzmann. He wrote the code for
  7. * bezier bicubic patches and generously provided us these enhancements.
  8. *
  9. * from Persistence of Vision(tm) Ray Tracer
  10. * Copyright 1996,1999 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. * NOTICE: This source code file is provided so that users may experiment
  13. * with enhancements to POV-Ray and to port the software to platforms other
  14. * than those supported by the POV-Ray Team. There are strict rules under
  15. * which you are permitted to use this file. The rules are in the file
  16. * named POVLEGAL.DOC which should be distributed with this file.
  17. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  19. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26. #include "frame.h"
  27. #include "vector.h"
  28. #include "povproto.h"
  29. #include "bezier.h"
  30. #include "matrices.h"
  31. #include "objects.h"
  32. #include "povray.h"
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36. #define BEZIER_EPSILON 1.0e-10
  37. #define BEZIER_TOLERANCE 1.0e-5
  38. /*****************************************************************************
  39. * Local typedefs
  40. ******************************************************************************/
  41. /*****************************************************************************
  42. * Static functions
  43. ******************************************************************************/
  44. static int InvertMatrix (VECTOR in[3], VECTOR out[3]);
  45. static void bezier_value (VECTOR(*Control_Points)[4][4], DBL u0, DBL v0, VECTOR P, VECTOR N);
  46. static int intersect_subpatch (BICUBIC_PATCH *, RAY *, VECTOR [3], DBL [3], DBL [3], DBL *, VECTOR , VECTOR , DBL *, DBL *);
  47. static void find_average (int, VECTOR *, VECTOR , DBL *);
  48. static int spherical_bounds_check (RAY *, VECTOR , DBL);
  49. static int intersect_bicubic_patch0 (RAY *, BICUBIC_PATCH *, ISTACK *);
  50. static DBL point_plane_distance (VECTOR , VECTOR , DBL *);
  51. static DBL determine_subpatch_flatness (VECTOR(*)[4][4]);
  52. static int flat_enough (BICUBIC_PATCH *, VECTOR(*)[4][4]);
  53. static void bezier_bounding_sphere (VECTOR(*)[4][4], VECTOR , DBL *);
  54. static int bezier_subpatch_intersect (RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, ISTACK *);
  55. static void bezier_split_left_right (VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]);
  56. static void bezier_split_up_down (VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]);
  57. static int bezier_subdivider (RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, int, ISTACK *);
  58. static void bezier_tree_deleter (BEZIER_NODE *Node);
  59. static BEZIER_NODE *bezier_tree_builder (BICUBIC_PATCH *Object, VECTOR(*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, int depth);
  60. static int bezier_tree_walker (RAY *, BICUBIC_PATCH *, BEZIER_NODE *, ISTACK *);
  61. static BEZIER_NODE *create_new_bezier_node (void);
  62. static BEZIER_VERTICES *create_bezier_vertex_block (void);
  63. static BEZIER_CHILDREN *create_bezier_child_block (void);
  64. static int subpatch_normal (VECTOR v1, VECTOR v2, VECTOR v3, VECTOR Result, DBL *d);
  65. static int All_Bicubic_Patch_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  66. static int Inside_Bicubic_Patch (VECTOR IPoint, OBJECT *Object);
  67. static void Bicubic_Patch_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  68. static BICUBIC_PATCH *Copy_Bicubic_Patch (OBJECT *Object);
  69. static void Translate_Bicubic_Patch (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  70. static void Rotate_Bicubic_Patch (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  71. static void Scale_Bicubic_Patch (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  72. static void Transform_Bicubic_Patch (OBJECT *Object, TRANSFORM *Trans);
  73. static void Invert_Bicubic_Patch (OBJECT *Object);
  74. static void Destroy_Bicubic_Patch (OBJECT *Object);
  75. /*****************************************************************************
  76. * Local variables
  77. ******************************************************************************/
  78. static METHODS Bicubic_Patch_Methods =
  79. {
  80. All_Bicubic_Patch_Intersections,
  81. Inside_Bicubic_Patch, Bicubic_Patch_Normal, (COPY_METHOD)Copy_Bicubic_Patch,
  82. Translate_Bicubic_Patch, Rotate_Bicubic_Patch,
  83. Scale_Bicubic_Patch, Transform_Bicubic_Patch, Invert_Bicubic_Patch,
  84. Destroy_Bicubic_Patch
  85. };
  86. static int max_depth_reached;
  87. static DBL C[4] = { 1.0, 3.0, 3.0, 1.0 };
  88. /*****************************************************************************
  89. *
  90. * FUNCTION
  91. *
  92. * create_new_bezier_node
  93. *
  94. * INPUT
  95. *
  96. * OUTPUT
  97. *
  98. * RETURNS
  99. *
  100. * AUTHOR
  101. *
  102. * Alexander Enzmann
  103. *
  104. * DESCRIPTION
  105. *
  106. * -
  107. *
  108. * CHANGES
  109. *
  110. * -
  111. *
  112. ******************************************************************************/
  113. static BEZIER_NODE *create_new_bezier_node()
  114. {
  115. BEZIER_NODE *Node = (BEZIER_NODE *)POV_MALLOC(sizeof(BEZIER_NODE), "bezier node");
  116. Node->Data_Ptr = NULL;
  117. return (Node);
  118. }
  119. /*****************************************************************************
  120. *
  121. * FUNCTION
  122. *
  123. * create_bezier_vertex_block
  124. *
  125. * INPUT
  126. *
  127. * OUTPUT
  128. *
  129. * RETURNS
  130. *
  131. * AUTHOR
  132. *
  133. * Alexander Enzmann
  134. *
  135. * DESCRIPTION
  136. *
  137. * -
  138. *
  139. * CHANGES
  140. *
  141. * -
  142. *
  143. ******************************************************************************/
  144. static BEZIER_VERTICES *create_bezier_vertex_block()
  145. {
  146. BEZIER_VERTICES *Vertices;
  147. Vertices = (BEZIER_VERTICES *)POV_MALLOC(sizeof(BEZIER_VERTICES), "bezier vertices");
  148. return (Vertices);
  149. }
  150. /*****************************************************************************
  151. *
  152. * FUNCTION
  153. *
  154. * create_bezier_child_block
  155. *
  156. * INPUT
  157. *
  158. * OUTPUT
  159. *
  160. * RETURNS
  161. *
  162. * AUTHOR
  163. *
  164. * Alexander Enzmann
  165. *
  166. * DESCRIPTION
  167. *
  168. * -
  169. *
  170. * CHANGES
  171. *
  172. * -
  173. *
  174. ******************************************************************************/
  175. static BEZIER_CHILDREN *create_bezier_child_block()
  176. {
  177. BEZIER_CHILDREN *Children;
  178. Children = (BEZIER_CHILDREN *)POV_MALLOC(sizeof(BEZIER_CHILDREN), "bezier children");
  179. return (Children);
  180. }
  181. /*****************************************************************************
  182. *
  183. * FUNCTION
  184. *
  185. * bezier_tree_builder
  186. *
  187. * INPUT
  188. *
  189. * OUTPUT
  190. *
  191. * RETURNS
  192. *
  193. * AUTHOR
  194. *
  195. * Alexander Enzmann
  196. *
  197. * DESCRIPTION
  198. *
  199. * -
  200. *
  201. * CHANGES
  202. *
  203. * -
  204. *
  205. ******************************************************************************/
  206. static BEZIER_NODE *bezier_tree_builder(BICUBIC_PATCH *Object, VECTOR (*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, int depth)
  207. {
  208. VECTOR Lower_Left[4][4], Lower_Right[4][4];
  209. VECTOR Upper_Left[4][4], Upper_Right[4][4];
  210. BEZIER_CHILDREN *Children;
  211. BEZIER_VERTICES *Vertices;
  212. BEZIER_NODE *Node = create_new_bezier_node();
  213. if (depth > max_depth_reached)
  214. {
  215. max_depth_reached = depth;
  216. }
  217. /* Build the bounding sphere for this subpatch. */
  218. bezier_bounding_sphere(Patch, Node->Center, &(Node->Radius_Squared));
  219. /*
  220. * If the patch is close to being flat, then just perform
  221. * a ray-plane intersection test.
  222. */
  223. if (flat_enough(Object, Patch))
  224. {
  225. /* The patch is now flat enough to simply store the corners. */
  226. Node->Node_Type = BEZIER_LEAF_NODE;
  227. Vertices = create_bezier_vertex_block();
  228. Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  229. Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  230. Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  231. Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  232. Vertices->uvbnds[0] = u0;
  233. Vertices->uvbnds[1] = u1;
  234. Vertices->uvbnds[2] = v0;
  235. Vertices->uvbnds[3] = v1;
  236. Node->Data_Ptr = (void *)Vertices;
  237. }
  238. else
  239. {
  240. if (depth >= Object->U_Steps)
  241. {
  242. if (depth >= Object->V_Steps)
  243. {
  244. /* We are at the max recursion depth. Just store corners. */
  245. Node->Node_Type = BEZIER_LEAF_NODE;
  246. Vertices = create_bezier_vertex_block();
  247. Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  248. Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  249. Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  250. Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  251. Vertices->uvbnds[0] = u0;
  252. Vertices->uvbnds[1] = u1;
  253. Vertices->uvbnds[2] = v0;
  254. Vertices->uvbnds[3] = v1;
  255. Node->Data_Ptr = (void *)Vertices;
  256. }
  257. else
  258. {
  259. bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  260. Node->Node_Type = BEZIER_INTERIOR_NODE;
  261. Children = create_bezier_child_block();
  262. Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  263. Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  264. Node->Count = 2;
  265. Node->Data_Ptr = (void *)Children;
  266. }
  267. }
  268. else
  269. {
  270. if (depth >= Object->V_Steps)
  271. {
  272. bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  273. Node->Node_Type = BEZIER_INTERIOR_NODE;
  274. Children = create_bezier_child_block();
  275. Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, v1, depth + 1);
  276. Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, v1, depth + 1);
  277. Node->Count = 2;
  278. Node->Data_Ptr = (void *)Children;
  279. }
  280. else
  281. {
  282. bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  283. bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  284. bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  285. Node->Node_Type = BEZIER_INTERIOR_NODE;
  286. Children = create_bezier_child_block();
  287. Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, (v0 + v1) / 2.0, depth + 1);
  288. Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, (u0 + u1) / 2.0, (v0 + v1) / 2.0, v1, depth + 1);
  289. Children->Children[2] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  290. Children->Children[3] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Right, (u0 + u1) / 2.0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  291. Node->Count = 4;
  292. Node->Data_Ptr = (void *)Children;
  293. }
  294. }
  295. }
  296. return (Node);
  297. }
  298. /*****************************************************************************
  299. *
  300. * FUNCTION
  301. *
  302. * bezier_value
  303. *
  304. * INPUT
  305. *
  306. * OUTPUT
  307. *
  308. * RETURNS
  309. *
  310. * AUTHOR
  311. *
  312. * Alexander Enzmann
  313. *
  314. * DESCRIPTION
  315. *
  316. * Determine the position and normal at a single coordinate
  317. * point (u, v) on a Bezier patch.
  318. *
  319. * CHANGES
  320. *
  321. * -
  322. *
  323. ******************************************************************************/
  324. static void bezier_value(VECTOR (*Control_Points)[4][4], DBL u0, DBL v0, VECTOR P, VECTOR N)
  325. {
  326. int i, j;
  327. DBL c, t, ut, vt;
  328. DBL u[4], uu[4], v[4], vv[4];
  329. DBL du[4], duu[4], dv[4], dvv[4];
  330. VECTOR U1, V1;
  331. /* Calculate binomial coefficients times coordinate positions. */
  332. u[0] = 1.0; uu[0] = 1.0; du[0] = 0.0; duu[0] = 0.0;
  333. v[0] = 1.0; vv[0] = 1.0; dv[0] = 0.0; dvv[0] = 0.0;
  334. for (i = 1; i < 4; i++)
  335. {
  336. u[i] = u[i - 1] * u0; uu[i] = uu[i - 1] * (1.0 - u0);
  337. v[i] = v[i - 1] * v0; vv[i] = vv[i - 1] * (1.0 - v0);
  338. du[i] = i * u[i - 1]; duu[i] = -i * uu[i - 1];
  339. dv[i] = i * v[i - 1]; dvv[i] = -i * vv[i - 1];
  340. }
  341. /* Now evaluate position and tangents based on control points. */
  342. Make_Vector(P, 0, 0, 0);
  343. Make_Vector(U1, 0, 0, 0);
  344. Make_Vector(V1, 0, 0, 0);
  345. for (i = 0; i < 4; i++)
  346. {
  347. for (j = 0; j < 4; j++)
  348. {
  349. c = C[i] * C[j];
  350. ut = u[i] * uu[3 - i];
  351. vt = v[j] * vv[3 - j];
  352. t = c * ut * vt;
  353. VAddScaledEq(P, t, (*Control_Points)[i][j]);
  354. t = c * vt * (du[i] * uu[3 - i] + u[i] * duu[3 - i]);
  355. VAddScaledEq(U1, t, (*Control_Points)[i][j]);
  356. t = c * ut * (dv[j] * vv[3 - j] + v[j] * dvv[3 - j]);
  357. VAddScaledEq(V1, t, (*Control_Points)[i][j]);
  358. }
  359. }
  360. /* Make the normal from the cross product of the tangents. */
  361. VCross(N, U1, V1);
  362. VDot(t, N, N);
  363. if (t > BEZIER_EPSILON)
  364. {
  365. t = 1.0 / sqrt(t);
  366. VScaleEq(N, t);
  367. }
  368. else
  369. {
  370. Make_Vector(N, 1, 0, 0)
  371. }
  372. }
  373. /*****************************************************************************
  374. *
  375. * FUNCTION
  376. *
  377. * subpatch_normal
  378. *
  379. * INPUT
  380. *
  381. * OUTPUT
  382. *
  383. * RETURNS
  384. *
  385. * AUTHOR
  386. *
  387. * Alexander Enzmann
  388. *
  389. * DESCRIPTION
  390. *
  391. * Calculate the normal to a subpatch (triangle) return the vector
  392. * <1.0 0.0 0.0> if the triangle is degenerate.
  393. *
  394. * CHANGES
  395. *
  396. * -
  397. *
  398. ******************************************************************************/
  399. static int subpatch_normal(VECTOR v1, VECTOR v2, VECTOR v3, VECTOR Result, DBL *d)
  400. {
  401. VECTOR V1, V2;
  402. DBL Length;
  403. VSub(V1, v1, v2);
  404. VSub(V2, v3, v2);
  405. VCross(Result, V1, V2);
  406. VLength(Length, Result);
  407. if (Length < BEZIER_EPSILON)
  408. {
  409. Make_Vector(Result, 1.0, 0.0, 0.0);
  410. *d = -1.0 * v1[X];
  411. return (0);
  412. }
  413. else
  414. {
  415. VInverseScale(Result, Result, Length);
  416. VDot(*d, Result, v1);
  417. *d = 0.0 - *d;
  418. return (1);
  419. }
  420. }
  421. /*****************************************************************************
  422. *
  423. * FUNCTION
  424. *
  425. * InvertMatrix
  426. *
  427. * INPUT
  428. *
  429. * OUTPUT
  430. *
  431. * RETURNS
  432. *
  433. * AUTHOR
  434. *
  435. * Alexander Enzmann
  436. *
  437. * DESCRIPTION
  438. *
  439. * -
  440. *
  441. * CHANGES
  442. *
  443. * -
  444. *
  445. ******************************************************************************/
  446. static int InvertMatrix(VECTOR in[3], VECTOR out[3])
  447. {
  448. int i;
  449. DBL det;
  450. out[0][X] = (in[1][Y] * in[2][Z] - in[1][Z] * in[2][Y]);
  451. out[1][X] = - (in[0][Y] * in[2][Z] - in[0][Z] * in[2][Y]);
  452. out[2][X] = (in[0][Y] * in[1][Z] - in[0][Z] * in[1][Y]);
  453. out[0][Y] = - (in[1][X] * in[2][Z] - in[1][Z] * in[2][X]);
  454. out[1][Y] = (in[0][X] * in[2][Z] - in[0][Z] * in[2][X]);
  455. out[2][Y] = - (in[0][X] * in[1][Z] - in[0][Z] * in[1][X]);
  456. out[0][Z] = (in[1][X] * in[2][Y] - in[1][Y] * in[2][X]);
  457. out[1][Z] = - (in[0][X] * in[2][Y] - in[0][Y] * in[2][X]);
  458. out[2][Z] = (in[0][X] * in[1][Y] - in[0][Y] * in[1][X]);
  459. det = in[0][X] * in[1][Y] * in[2][Z] +
  460. in[0][Y] * in[1][Z] * in[2][X] +
  461. in[0][Z] * in[1][X] * in[2][Y] -
  462. in[0][Z] * in[1][Y] * in[2][X] -
  463. in[0][X] * in[1][Z] * in[2][Y] -
  464. in[0][Y] * in[1][X] * in[2][Z];
  465. if (fabs(det) < BEZIER_EPSILON)
  466. {
  467. return (0);
  468. }
  469. det = 1.0 / det;
  470. for (i = 0; i < 3; i++)
  471. {
  472. VScaleEq(out[i], det)
  473. }
  474. return (1);
  475. }
  476. /*****************************************************************************
  477. *
  478. * FUNCTION
  479. *
  480. * intersect_subpatch
  481. *
  482. * INPUT
  483. *
  484. * OUTPUT
  485. *
  486. * RETURNS
  487. *
  488. * AUTHOR
  489. *
  490. * Alexander Enzmann
  491. *
  492. * DESCRIPTION
  493. *
  494. * -
  495. *
  496. * CHANGES
  497. *
  498. * -
  499. *
  500. ******************************************************************************/
  501. static int intersect_subpatch(BICUBIC_PATCH *Shape, RAY *ray, VECTOR V1[3], DBL uu[3], DBL vv[3], DBL *Depth, VECTOR P, VECTOR N, DBL *u, DBL *v)
  502. {
  503. DBL d, n, a, b, r;
  504. VECTOR B[3], IB[3], NN[3], Q, T1;
  505. VSub(B[0], V1[1], V1[0]);
  506. VSub(B[1], V1[2], V1[0]);
  507. VCross(B[2], B[0], B[1]);
  508. VDot(d, B[2], B[2]);
  509. if (d < BEZIER_EPSILON)
  510. {
  511. return (0);
  512. }
  513. d = 1.0 / sqrt(d);
  514. VScaleEq(B[2], d);
  515. /* Degenerate triangle. */
  516. if (!InvertMatrix(B, IB))
  517. {
  518. return (0);
  519. }
  520. VDot(d, ray->Direction, IB[2]);
  521. if (fabs(d) < BEZIER_EPSILON)
  522. {
  523. return (0);
  524. }
  525. VSub(Q, V1[0], ray->Initial);
  526. VDot(n, Q, IB[2]);
  527. *Depth = n / d;
  528. if (*Depth < BEZIER_TOLERANCE)
  529. {
  530. return (0);
  531. }
  532. VScale(T1, ray->Direction, *Depth);
  533. VAdd(P, ray->Initial, T1);
  534. VSub(Q, P, V1[0]);
  535. VDot(a, Q, IB[0]);
  536. VDot(b, Q, IB[1]);
  537. if ((a < 0.0) || (b < 0.0) || (a + b > 1.0))
  538. {
  539. return (0);
  540. }
  541. r = 1.0 - a - b;
  542. Make_Vector(N, 0.0, 0.0, 0.0);
  543. bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[0], vv[0], T1, NN[0]);
  544. bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[1], vv[1], T1, NN[1]);
  545. bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[2], vv[2], T1, NN[2]);
  546. VScale(T1, NN[0], r); VAddEq(N, T1);
  547. VScale(T1, NN[1], a); VAddEq(N, T1);
  548. VScale(T1, NN[2], b); VAddEq(N, T1);
  549. *u = r * uu[0] + a * uu[1] + b * uu[2];
  550. *v = r * vv[0] + a * vv[1] + b * vv[2];
  551. VDot(d, N, N);
  552. if (d > BEZIER_EPSILON)
  553. {
  554. d = 1.0 / sqrt(d);
  555. VScaleEq(N, d);
  556. }
  557. else
  558. {
  559. Make_Vector(N, 1, 0, 0);
  560. }
  561. return (1);
  562. }
  563. /*****************************************************************************
  564. *
  565. * FUNCTION
  566. *
  567. * find_average
  568. *
  569. * INPUT
  570. *
  571. * OUTPUT
  572. *
  573. * RETURNS
  574. *
  575. * AUTHOR
  576. *
  577. * Alexander Enzmann
  578. *
  579. * DESCRIPTION
  580. *
  581. * Find a sphere that contains all of the points in the list "vectors".
  582. *
  583. * CHANGES
  584. *
  585. * -
  586. *
  587. ******************************************************************************/
  588. static void find_average(int vector_count, VECTOR *vectors, VECTOR center, DBL *radius)
  589. {
  590. int i;
  591. DBL r0, r1, xc = 0, yc = 0, zc = 0;
  592. DBL x0, y0, z0;
  593. for (i = 0; i < vector_count; i++)
  594. {
  595. xc += vectors[i][X];
  596. yc += vectors[i][Y];
  597. zc += vectors[i][Z];
  598. }
  599. xc /= (DBL)vector_count;
  600. yc /= (DBL)vector_count;
  601. zc /= (DBL)vector_count;
  602. r0 = 0.0;
  603. for (i = 0; i < vector_count; i++)
  604. {
  605. x0 = vectors[i][X] - xc;
  606. y0 = vectors[i][Y] - yc;
  607. z0 = vectors[i][Z] - zc;
  608. r1 = x0 * x0 + y0 * y0 + z0 * z0;
  609. if (r1 > r0)
  610. {
  611. r0 = r1;
  612. }
  613. }
  614. Make_Vector(center, xc, yc, zc);
  615. *radius = r0;
  616. }
  617. /*****************************************************************************
  618. *
  619. * FUNCTION
  620. *
  621. * spherical_bounds_check
  622. *
  623. * INPUT
  624. *
  625. * OUTPUT
  626. *
  627. * RETURNS
  628. *
  629. * AUTHOR
  630. *
  631. * Alexander Enzmann
  632. *
  633. * DESCRIPTION
  634. *
  635. * -
  636. *
  637. * CHANGES
  638. *
  639. * -
  640. *
  641. ******************************************************************************/
  642. static int spherical_bounds_check(RAY *Ray, VECTOR center, DBL radius)
  643. {
  644. DBL x, y, z, dist1, dist2;
  645. x = center[X] - Ray->Initial[X];
  646. y = center[Y] - Ray->Initial[Y];
  647. z = center[Z] - Ray->Initial[Z];
  648. dist1 = x * x + y * y + z * z;
  649. if (dist1 < radius)
  650. {
  651. /* ray starts inside sphere - assume it intersects. */
  652. return (1);
  653. }
  654. else
  655. {
  656. dist2 = x*Ray->Direction[X] + y*Ray->Direction[Y] + z*Ray->Direction[Z];
  657. dist2 *= dist2;
  658. if ((dist2 > 0) && (dist1 - dist2 < radius))
  659. {
  660. return (1);
  661. }
  662. }
  663. return (0);
  664. }
  665. /*****************************************************************************
  666. *
  667. * FUNCTION
  668. *
  669. * bezier_bounding_sphere
  670. *
  671. * INPUT
  672. *
  673. * OUTPUT
  674. *
  675. * RETURNS
  676. *
  677. * AUTHOR
  678. *
  679. * Alexander Enzmann
  680. *
  681. * DESCRIPTION
  682. *
  683. * Find a sphere that bounds all of the control points of a Bezier patch.
  684. * The values returned are: the center of the bounding sphere, and the
  685. * square of the radius of the bounding sphere.
  686. *
  687. * CHANGES
  688. *
  689. * -
  690. *
  691. ******************************************************************************/
  692. static void bezier_bounding_sphere(VECTOR (*Patch)[4][4], VECTOR center, DBL *radius)
  693. {
  694. int i, j;
  695. DBL r0, r1, xc = 0, yc = 0, zc = 0;
  696. DBL x0, y0, z0;
  697. for (i = 0; i < 4; i++)
  698. {
  699. for (j = 0; j < 4; j++)
  700. {
  701. xc += (*Patch)[i][j][X];
  702. yc += (*Patch)[i][j][Y];
  703. zc += (*Patch)[i][j][Z];
  704. }
  705. }
  706. xc /= 16.0;
  707. yc /= 16.0;
  708. zc /= 16.0;
  709. r0 = 0.0;
  710. for (i = 0; i < 4; i++)
  711. {
  712. for (j = 0; j < 4; j++)
  713. {
  714. x0 = (*Patch)[i][j][X] - xc;
  715. y0 = (*Patch)[i][j][Y] - yc;
  716. z0 = (*Patch)[i][j][Z] - zc;
  717. r1 = x0 * x0 + y0 * y0 + z0 * z0;
  718. if (r1 > r0)
  719. {
  720. r0 = r1;
  721. }
  722. }
  723. }
  724. Make_Vector(center, xc, yc, zc);
  725. *radius = r0;
  726. }
  727. /*****************************************************************************
  728. *
  729. * FUNCTION
  730. *
  731. * Precompute_Patch_Values
  732. *
  733. * INPUT
  734. *
  735. * OUTPUT
  736. *
  737. * RETURNS
  738. *
  739. * AUTHOR
  740. *
  741. * Alexander Enzmann
  742. *
  743. * DESCRIPTION
  744. *
  745. * Precompute grid points and normals for a bezier patch.
  746. *
  747. * CHANGES
  748. *
  749. * -
  750. *
  751. ******************************************************************************/
  752. void Precompute_Patch_Values(BICUBIC_PATCH *Shape)
  753. {
  754. int i, j;
  755. VECTOR Control_Points[16];
  756. VECTOR(*Patch_Ptr)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  757. /* Calculate the bounding sphere for the entire patch. */
  758. for (i = 0; i < 4; i++)
  759. {
  760. for (j = 0; j < 4; j++)
  761. {
  762. Assign_Vector(Control_Points[4*i + j], Shape->Control_Points[i][j]);
  763. }
  764. }
  765. find_average(16, Control_Points, Shape->Bounding_Sphere_Center, &Shape->Bounding_Sphere_Radius);
  766. if (Shape->Patch_Type != 0)
  767. {
  768. if (Shape->Node_Tree != NULL)
  769. {
  770. bezier_tree_deleter(Shape->Node_Tree);
  771. }
  772. Shape->Node_Tree = bezier_tree_builder(Shape, Patch_Ptr, 0.0, 1.0, 0.0, 1.0, 0);
  773. }
  774. }
  775. /*****************************************************************************
  776. *
  777. * FUNCTION
  778. *
  779. * point_plane_distance
  780. *
  781. * INPUT
  782. *
  783. * OUTPUT
  784. *
  785. * RETURNS
  786. *
  787. * AUTHOR
  788. *
  789. * Alexander Enzmann
  790. *
  791. * DESCRIPTION
  792. *
  793. * Determine the distance from a point to a plane.
  794. *
  795. * CHANGES
  796. *
  797. * -
  798. *
  799. ******************************************************************************/
  800. static DBL point_plane_distance(VECTOR p, VECTOR n, DBL *d)
  801. {
  802. DBL temp1, temp2;
  803. VDot(temp1, p, n);
  804. temp1 += *d;
  805. VLength(temp2, n);
  806. if (fabs(temp2) < EPSILON)
  807. {
  808. return (0.0);
  809. }
  810. temp1 /= temp2;
  811. return (temp1);
  812. }
  813. /*****************************************************************************
  814. *
  815. * FUNCTION
  816. *
  817. * bezier_subpatch_intersect
  818. *
  819. * INPUT
  820. *
  821. * OUTPUT
  822. *
  823. * RETURNS
  824. *
  825. * AUTHOR
  826. *
  827. * Alexander Enzmann
  828. *
  829. * DESCRIPTION
  830. *
  831. * -
  832. *
  833. * CHANGES
  834. *
  835. * -
  836. *
  837. ******************************************************************************/
  838. static int bezier_subpatch_intersect(RAY *ray, BICUBIC_PATCH *Shape, VECTOR (*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, ISTACK *Depth_Stack)
  839. {
  840. int cnt = 0;
  841. VECTOR V1[3];
  842. DBL u, v, Depth, uu[3], vv[3];
  843. VECTOR P, N;
  844. Assign_Vector(V1[0], (*Patch)[0][0]);
  845. Assign_Vector(V1[1], (*Patch)[0][3]);
  846. Assign_Vector(V1[2], (*Patch)[3][3]);
  847. uu[0] = u0; uu[1] = u0; uu[2] = u1;
  848. vv[0] = v0; vv[1] = v1; vv[2] = v1;
  849. if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  850. {
  851. push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  852. cnt++;
  853. }
  854. Assign_Vector(V1[1], V1[2]);
  855. Assign_Vector(V1[2], (*Patch)[3][0]);
  856. uu[1] = uu[2]; uu[2] = u1;
  857. vv[1] = vv[2]; vv[2] = v0;
  858. if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  859. {
  860. push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  861. cnt++;
  862. }
  863. return (cnt);
  864. }
  865. /*****************************************************************************
  866. *
  867. * FUNCTION
  868. *
  869. * bezier_split_left_right
  870. *
  871. * INPUT
  872. *
  873. * OUTPUT
  874. *
  875. * RETURNS
  876. *
  877. * AUTHOR
  878. *
  879. * Alexander Enzmann
  880. *
  881. * DESCRIPTION
  882. *
  883. * -
  884. *
  885. * CHANGES
  886. *
  887. * -
  888. *
  889. ******************************************************************************/
  890. static void bezier_split_left_right(VECTOR (*Patch)[4][4], VECTOR (*Left_Patch)[4][4], VECTOR (*Right_Patch)[4][4])
  891. {
  892. int i, j;
  893. VECTOR Temp1[4], Temp2[4], Half;
  894. for (i = 0; i < 4; i++)
  895. {
  896. Assign_Vector(Temp1[0], (*Patch)[0][i]);
  897. VHalf(Temp1[1], (*Patch)[0][i], (*Patch)[1][i]);
  898. VHalf(Half, (*Patch)[1][i], (*Patch)[2][i]);
  899. VHalf(Temp1[2], Temp1[1], Half);
  900. VHalf(Temp2[2], (*Patch)[2][i], (*Patch)[3][i]);
  901. VHalf(Temp2[1], Half, Temp2[2]);
  902. VHalf(Temp1[3], Temp1[2], Temp2[1]);
  903. Assign_Vector(Temp2[0], Temp1[3]);
  904. Assign_Vector(Temp2[3], (*Patch)[3][i]);
  905. for (j = 0; j < 4; j++)
  906. {
  907. Assign_Vector((*Left_Patch)[j][i], Temp1[j]);
  908. Assign_Vector((*Right_Patch)[j][i], Temp2[j]);
  909. }
  910. }
  911. }
  912. /*****************************************************************************
  913. *
  914. * FUNCTION
  915. *
  916. * bezier_split_up_down
  917. *
  918. * INPUT
  919. *
  920. * OUTPUT
  921. *
  922. * RETURNS
  923. *
  924. * AUTHOR
  925. *
  926. * Alexander Enzmann
  927. *
  928. * DESCRIPTION
  929. *
  930. * -
  931. *
  932. * CHANGES
  933. *
  934. * -
  935. *
  936. ******************************************************************************/
  937. static void bezier_split_up_down(VECTOR (*Patch)[4][4], VECTOR (*Bottom_Patch)[4][4], VECTOR (*Top_Patch)[4][4])
  938. {
  939. int i, j;
  940. VECTOR Temp1[4], Temp2[4], Half;
  941. for (i = 0; i < 4; i++)
  942. {
  943. Assign_Vector(Temp1[0], (*Patch)[i][0]);
  944. VHalf(Temp1[1], (*Patch)[i][0], (*Patch)[i][1]);
  945. VHalf(Half, (*Patch)[i][1], (*Patch)[i][2]);
  946. VHalf(Temp1[2], Temp1[1], Half);
  947. VHalf(Temp2[2], (*Patch)[i][2], (*Patch)[i][3]);
  948. VHalf(Temp2[1], Half, Temp2[2]);
  949. VHalf(Temp1[3], Temp1[2], Temp2[1]);
  950. Assign_Vector(Temp2[0], Temp1[3]);
  951. Assign_Vector(Temp2[3], (*Patch)[i][3]);
  952. for (j = 0; j < 4; j++)
  953. {
  954. Assign_Vector((*Bottom_Patch)[i][j], Temp1[j]);
  955. Assign_Vector((*Top_Patch)[i][j] , Temp2[j]);
  956. }
  957. }
  958. }
  959. /*****************************************************************************
  960. *
  961. * FUNCTION
  962. *
  963. * determine_subpatch_flatness
  964. *
  965. * INPUT
  966. *
  967. * OUTPUT
  968. *
  969. * RETURNS
  970. *
  971. * AUTHOR
  972. *
  973. * Alexander Enzmann
  974. *
  975. * DESCRIPTION
  976. *
  977. * See how close to a plane a subpatch is, the patch must have at least
  978. * three distinct vertices. A negative result from this function indicates
  979. * that a degenerate value of some sort was encountered.
  980. *
  981. * CHANGES
  982. *
  983. * -
  984. *
  985. ******************************************************************************/
  986. static DBL determine_subpatch_flatness(VECTOR (*Patch)[4][4])
  987. {
  988. int i, j;
  989. DBL d, dist, temp1;
  990. VECTOR vertices[4], n, TempV;
  991. Assign_Vector(vertices[0], (*Patch)[0][0]);
  992. Assign_Vector(vertices[1], (*Patch)[0][3]);
  993. VSub(TempV, vertices[0], vertices[1]);
  994. VLength(temp1, TempV);
  995. if (fabs(temp1) < EPSILON)
  996. {
  997. /*
  998. * Degenerate in the V direction for U = 0. This is ok if the other
  999. * two corners are distinct from the lower left corner - I'm sure there
  1000. * are cases where the corners coincide and the middle has good values,
  1001. * but that is somewhat pathalogical and won't be considered.
  1002. */
  1003. Assign_Vector(vertices[1], (*Patch)[3][3]);
  1004. VSub(TempV, vertices[0], vertices[1]);
  1005. VLength(temp1, TempV);
  1006. if (fabs(temp1) < EPSILON)
  1007. {
  1008. return (-1.0);
  1009. }
  1010. Assign_Vector(vertices[2], (*Patch)[3][0]);
  1011. VSub(TempV, vertices[0], vertices[1]);
  1012. VLength(temp1, TempV);
  1013. if (fabs(temp1) < EPSILON)
  1014. {
  1015. return (-1.0);
  1016. }
  1017. VSub(TempV, vertices[1], vertices[2]);
  1018. VLength(temp1, TempV);
  1019. if (fabs(temp1) < EPSILON)
  1020. {
  1021. return (-1.0);
  1022. }
  1023. }
  1024. else
  1025. {
  1026. Assign_Vector(vertices[2], (*Patch)[3][0]);
  1027. VSub(TempV, vertices[0], vertices[1]);
  1028. VLength(temp1, TempV);
  1029. if (fabs(temp1) < EPSILON)
  1030. {
  1031. Assign_Vector(vertices[2], (*Patch)[3][3]);
  1032. VSub(TempV, vertices[0], vertices[2]);
  1033. VLength(temp1, TempV);
  1034. if (fabs(temp1) < EPSILON)
  1035. {
  1036. return (-1.0);
  1037. }
  1038. VSub(TempV, vertices[1], vertices[2]);
  1039. VLength(temp1, TempV);
  1040. if (fabs(temp1) < EPSILON)
  1041. {
  1042. return (-1.0);
  1043. }
  1044. }
  1045. else
  1046. {
  1047. VSub(TempV, vertices[1], vertices[2]);
  1048. VLength(temp1, TempV);
  1049. if (fabs(temp1) < EPSILON)
  1050. {
  1051. return (-1.0);
  1052. }
  1053. }
  1054. }
  1055. /*
  1056. * Now that a good set of candidate points has been found,
  1057. * find the plane equations for the patch.
  1058. */
  1059. if (subpatch_normal(vertices[0], vertices[1], vertices[2], n, &d))
  1060. {
  1061. /*
  1062. * Step through all vertices and see what the maximum
  1063. * distance from the plane happens to be.
  1064. */
  1065. dist = 0.0;
  1066. for (i = 0; i < 4; i++)
  1067. {
  1068. for (j = 0; j < 4; j++)
  1069. {
  1070. temp1 = fabs(point_plane_distance(((*Patch)[i][j]), n, &d));
  1071. if (temp1 > dist)
  1072. {
  1073. dist = temp1;
  1074. }
  1075. }
  1076. }
  1077. return (dist);
  1078. }
  1079. else
  1080. {
  1081. /*
  1082. Debug_Info("Subpatch normal failed in determine_subpatch_flatness\n");
  1083. */
  1084. return (-1.0);
  1085. }
  1086. }
  1087. /*****************************************************************************
  1088. *
  1089. * FUNCTION
  1090. *
  1091. * flat_enough
  1092. *
  1093. * INPUT
  1094. *
  1095. * OUTPUT
  1096. *
  1097. * RETURNS
  1098. *
  1099. * AUTHOR
  1100. *
  1101. * Alexander Enzmann
  1102. *
  1103. * DESCRIPTION
  1104. *
  1105. * -
  1106. *
  1107. * CHANGES
  1108. *
  1109. * -
  1110. *
  1111. ******************************************************************************/
  1112. static int flat_enough(BICUBIC_PATCH *Object, VECTOR (*Patch)[4][4])
  1113. {
  1114. DBL Dist;
  1115. Dist = determine_subpatch_flatness(Patch);
  1116. if (Dist < 0.0)
  1117. {
  1118. return (0);
  1119. }
  1120. else
  1121. {
  1122. if (Dist < Object->Flatness_Value)
  1123. {
  1124. return (1);
  1125. }
  1126. else
  1127. {
  1128. return (0);
  1129. }
  1130. }
  1131. }
  1132. /*****************************************************************************
  1133. *
  1134. * FUNCTION
  1135. *
  1136. * bezier_subdivider
  1137. *
  1138. * INPUT
  1139. *
  1140. * OUTPUT
  1141. *
  1142. * RETURNS
  1143. *
  1144. * AUTHOR
  1145. *
  1146. * Alexander Enzmann
  1147. *
  1148. * DESCRIPTION
  1149. *
  1150. * -
  1151. *
  1152. * CHANGES
  1153. *
  1154. * -
  1155. *
  1156. ******************************************************************************/
  1157. static int bezier_subdivider(RAY *Ray, BICUBIC_PATCH *Object, VECTOR (*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1,
  1158. int recursion_depth, ISTACK *Depth_Stack)
  1159. {
  1160. int cnt = 0;
  1161. DBL ut, vt, radius;
  1162. VECTOR Lower_Left[4][4], Lower_Right[4][4];
  1163. VECTOR Upper_Left[4][4], Upper_Right[4][4];
  1164. VECTOR center;
  1165. /*
  1166. * Make sure the ray passes through a sphere bounding
  1167. * the control points of the patch.
  1168. */
  1169. bezier_bounding_sphere(Patch, center, &radius);
  1170. if (!spherical_bounds_check(Ray, center, radius))
  1171. {
  1172. return (0);
  1173. }
  1174. /*
  1175. * If the patch is close to being flat, then just
  1176. * perform a ray-plane intersection test.
  1177. */
  1178. if (flat_enough(Object, Patch))
  1179. {
  1180. return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1181. }
  1182. if (recursion_depth >= Object->U_Steps)
  1183. {
  1184. if (recursion_depth >= Object->V_Steps)
  1185. {
  1186. return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1187. }
  1188. else
  1189. {
  1190. bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  1191. vt = (v1 + v0) / 2.0;
  1192. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1193. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1194. }
  1195. }
  1196. else
  1197. {
  1198. if (recursion_depth >= Object->V_Steps)
  1199. {
  1200. bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1201. ut = (u1 + u0) / 2.0;
  1202. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, v1, recursion_depth + 1, Depth_Stack);
  1203. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, v1, recursion_depth + 1, Depth_Stack);
  1204. }
  1205. else
  1206. {
  1207. ut = (u1 + u0) / 2.0;
  1208. vt = (v1 + v0) / 2.0;
  1209. bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1210. bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left) ;
  1211. bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  1212. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, vt, recursion_depth + 1, Depth_Stack);
  1213. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, ut, vt, v1, recursion_depth + 1, Depth_Stack);
  1214. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1215. cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Right, ut, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1216. }
  1217. }
  1218. return (cnt);
  1219. }
  1220. /*****************************************************************************
  1221. *
  1222. * FUNCTION
  1223. *
  1224. * bezier_tree_deleter
  1225. *
  1226. * INPUT
  1227. *
  1228. * OUTPUT
  1229. *
  1230. * RETURNS
  1231. *
  1232. * AUTHOR
  1233. *
  1234. * Alexander Enzmann
  1235. *
  1236. * DESCRIPTION
  1237. *
  1238. * -
  1239. *
  1240. * CHANGES
  1241. *
  1242. * -
  1243. *
  1244. ******************************************************************************/
  1245. static void bezier_tree_deleter(BEZIER_NODE *Node)
  1246. {
  1247. int i;
  1248. BEZIER_CHILDREN *Children;
  1249. /* If this is an interior node then continue the descent. */
  1250. if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1251. {
  1252. Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1253. for (i = 0; i < Node->Count; i++)
  1254. {
  1255. bezier_tree_deleter(Children->Children[i]);
  1256. }
  1257. POV_FREE(Children);
  1258. }
  1259. else
  1260. {
  1261. if (Node->Node_Type == BEZIER_LEAF_NODE)
  1262. {
  1263. /* Free the memory used for the vertices. */
  1264. POV_FREE(Node->Data_Ptr);
  1265. }
  1266. }
  1267. /* Free the memory used for the node. */
  1268. POV_FREE(Node);
  1269. }
  1270. /*****************************************************************************
  1271. *
  1272. * FUNCTION
  1273. *
  1274. * bezier_tree_walker
  1275. *
  1276. * INPUT
  1277. *
  1278. * OUTPUT
  1279. *
  1280. * RETURNS
  1281. *
  1282. * AUTHOR
  1283. *
  1284. * Alexander Enzmann
  1285. *
  1286. * DESCRIPTION
  1287. *
  1288. * -
  1289. *
  1290. * CHANGES
  1291. *
  1292. * -
  1293. *
  1294. ******************************************************************************/
  1295. static int bezier_tree_walker(RAY *Ray, BICUBIC_PATCH *Shape, BEZIER_NODE *Node, ISTACK *Depth_Stack)
  1296. {
  1297. int i, cnt = 0;
  1298. DBL Depth, u, v, uu[3], vv[3];
  1299. VECTOR N, P, V1[3];
  1300. BEZIER_CHILDREN *Children;
  1301. BEZIER_VERTICES *Vertices;
  1302. /*
  1303. * Make sure the ray passes through a sphere bounding
  1304. * the control points of the patch.
  1305. */
  1306. if (!spherical_bounds_check(Ray, Node->Center, Node->Radius_Squared))
  1307. {
  1308. return (0);
  1309. }
  1310. /*
  1311. * If this is an interior node then continue the descent,
  1312. * else do a check against the vertices.
  1313. */
  1314. if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1315. {
  1316. Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1317. for (i = 0; i < Node->Count; i++)
  1318. {
  1319. cnt += bezier_tree_walker(Ray, Shape, Children->Children[i], Depth_Stack);
  1320. }
  1321. }
  1322. else if (Node->Node_Type == BEZIER_LEAF_NODE)
  1323. {
  1324. Vertices = (BEZIER_VERTICES *)Node->Data_Ptr;
  1325. Assign_Vector(V1[0], Vertices->Vertices[0]);
  1326. Assign_Vector(V1[1], Vertices->Vertices[1]);
  1327. Assign_Vector(V1[2], Vertices->Vertices[2]);
  1328. uu[0] = Vertices->uvbnds[0];
  1329. uu[1] = Vertices->uvbnds[0];
  1330. uu[2] = Vertices->uvbnds[1];
  1331. vv[0] = Vertices->uvbnds[2];
  1332. vv[1] = Vertices->uvbnds[3];
  1333. vv[2] = Vertices->uvbnds[3];
  1334. /*
  1335. * Triangulate this subpatch, then check for
  1336. * intersections in the triangles.
  1337. */
  1338. if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1339. {
  1340. push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1341. cnt++;
  1342. }
  1343. Assign_Vector(V1[1], V1[2]);
  1344. Assign_Vector(V1[2], Vertices->Vertices[3]);
  1345. uu[1] = uu[2]; uu[2] = Vertices->uvbnds[1];
  1346. vv[1] = vv[2]; vv[2] = Vertices->uvbnds[2];
  1347. if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1348. {
  1349. push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1350. cnt++;
  1351. }
  1352. }
  1353. else
  1354. {
  1355. Error("Bad Node type in bezier_tree_walker().\n");
  1356. }
  1357. return (cnt);
  1358. }
  1359. /*****************************************************************************
  1360. *
  1361. * FUNCTION
  1362. *
  1363. * intersect_bicubic_patch0
  1364. *
  1365. * INPUT
  1366. *
  1367. * OUTPUT
  1368. *
  1369. * RETURNS
  1370. *
  1371. * AUTHOR
  1372. *
  1373. * Alexander Enzmann
  1374. *
  1375. * DESCRIPTION
  1376. *
  1377. * -
  1378. *
  1379. * CHANGES
  1380. *
  1381. * -
  1382. *
  1383. ******************************************************************************/
  1384. static int intersect_bicubic_patch0(RAY *Ray, BICUBIC_PATCH *Shape, ISTACK *Depth_Stack)
  1385. {
  1386. VECTOR(*Patch)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  1387. return (bezier_subdivider(Ray, Shape, Patch, 0.0, 1.0, 0.0, 1.0, 0, Depth_Stack));
  1388. }
  1389. /*****************************************************************************
  1390. *
  1391. * FUNCTION
  1392. *
  1393. * All_Bicubic_Patch_Intersections
  1394. *
  1395. * INPUT
  1396. *
  1397. * OUTPUT
  1398. *
  1399. * RETURNS
  1400. *
  1401. * AUTHOR
  1402. *
  1403. * Alexander Enzmann
  1404. *
  1405. * DESCRIPTION
  1406. *
  1407. * -
  1408. *
  1409. * CHANGES
  1410. *
  1411. * -
  1412. *
  1413. ******************************************************************************/
  1414. static int All_Bicubic_Patch_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  1415. {
  1416. int Found, cnt = 0;
  1417. Found = FALSE;
  1418. Increase_Counter(stats[Ray_Bicubic_Tests]);
  1419. switch (((BICUBIC_PATCH *)Object)->Patch_Type)
  1420. {
  1421. case 0:
  1422. cnt = intersect_bicubic_patch0(Ray, ((BICUBIC_PATCH *)Object), Depth_Stack);
  1423. break;
  1424. case 1:
  1425. cnt = bezier_tree_walker(Ray, (BICUBIC_PATCH *)Object, ((BICUBIC_PATCH *)Object)->Node_Tree, Depth_Stack);
  1426. break;
  1427. default:
  1428. Error("Bad patch type in All_Bicubic_Patch_Intersections.\n");
  1429. }
  1430. if (cnt > 0)
  1431. {
  1432. Increase_Counter(stats[Ray_Bicubic_Tests_Succeeded]);
  1433. Found = TRUE;
  1434. }
  1435. return (Found);
  1436. }
  1437. /*****************************************************************************
  1438. *
  1439. * FUNCTION
  1440. *
  1441. * Inside_Bicubic_Patch
  1442. *
  1443. * INPUT
  1444. *
  1445. * OUTPUT
  1446. *
  1447. * RETURNS
  1448. *
  1449. * AUTHOR
  1450. *
  1451. * Alexander Enzmann
  1452. *
  1453. * DESCRIPTION
  1454. *
  1455. * A patch is not a solid, so an inside test doesn't make sense.
  1456. *
  1457. * CHANGES
  1458. *
  1459. * -
  1460. *
  1461. ******************************************************************************/
  1462. static int Inside_Bicubic_Patch(VECTOR IPoint, OBJECT *Object)
  1463. {
  1464. return (0);
  1465. }
  1466. /*****************************************************************************
  1467. *
  1468. * FUNCTION
  1469. *
  1470. * Bicubic_Patch_Normal
  1471. *
  1472. * INPUT
  1473. *
  1474. * OUTPUT
  1475. *
  1476. * RETURNS
  1477. *
  1478. * AUTHOR
  1479. *
  1480. * Alexander Enzmann
  1481. *
  1482. * DESCRIPTION
  1483. *
  1484. * -
  1485. *
  1486. * CHANGES
  1487. *
  1488. * -
  1489. *
  1490. ******************************************************************************/
  1491. static void Bicubic_Patch_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  1492. {
  1493. /* Use preocmputed normal. */
  1494. Assign_Vector(Result, Inter->INormal);
  1495. }
  1496. /*****************************************************************************
  1497. *
  1498. * FUNCTION
  1499. *
  1500. * Translate_Bicubic_Patch
  1501. *
  1502. * INPUT
  1503. *
  1504. * OUTPUT
  1505. *
  1506. * RETURNS
  1507. *
  1508. * AUTHOR
  1509. *
  1510. * Alexander Enzmann
  1511. *
  1512. * DESCRIPTION
  1513. *
  1514. * -
  1515. *
  1516. * CHANGES
  1517. *
  1518. * -
  1519. *
  1520. ******************************************************************************/
  1521. static void Translate_Bicubic_Patch(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1522. {
  1523. int i, j;
  1524. BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  1525. for (i = 0; i < 4; i++)
  1526. {
  1527. for (j = 0; j < 4; j++)
  1528. {
  1529. VAdd(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector)
  1530. }
  1531. }
  1532. Precompute_Patch_Values(Patch);
  1533. Compute_Bicubic_Patch_BBox(Patch);
  1534. }
  1535. /*****************************************************************************
  1536. *
  1537. * FUNCTION
  1538. *
  1539. * Rotate_Bicubic_Patch
  1540. *
  1541. * INPUT
  1542. *
  1543. * OUTPUT
  1544. *
  1545. * RETURNS
  1546. *
  1547. * AUTHOR
  1548. *
  1549. * Alexander Enzmann
  1550. *
  1551. * DESCRIPTION
  1552. *
  1553. * -
  1554. *
  1555. * CHANGES
  1556. *
  1557. * -
  1558. *
  1559. ******************************************************************************/
  1560. static void Rotate_Bicubic_Patch(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1561. {
  1562. Transform_Bicubic_Patch(Object, Trans);
  1563. }
  1564. /*****************************************************************************
  1565. *
  1566. * FUNCTION
  1567. *
  1568. * Scale_Bicubic_Patch
  1569. *
  1570. * INPUT
  1571. *
  1572. * OUTPUT
  1573. *
  1574. * RETURNS
  1575. *
  1576. * AUTHOR
  1577. *
  1578. * Alexander Enzmann
  1579. *
  1580. * DESCRIPTION
  1581. *
  1582. * -
  1583. *
  1584. * CHANGES
  1585. *
  1586. * -
  1587. *
  1588. ******************************************************************************/
  1589. static void Scale_Bicubic_Patch(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1590. {
  1591. int i, j;
  1592. BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  1593. for (i = 0; i < 4; i++)
  1594. {
  1595. for (j = 0; j < 4; j++)
  1596. {
  1597. VEvaluate(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector);
  1598. }
  1599. }
  1600. Precompute_Patch_Values(Patch);
  1601. Compute_Bicubic_Patch_BBox(Patch);
  1602. }
  1603. /*****************************************************************************
  1604. *
  1605. * FUNCTION
  1606. *
  1607. * Transform_Bicubic_Patch
  1608. *
  1609. * INPUT
  1610. *
  1611. * OUTPUT
  1612. *
  1613. * RETURNS
  1614. *
  1615. * AUTHOR
  1616. *
  1617. * Alexander Enzmann
  1618. *
  1619. * DESCRIPTION
  1620. *
  1621. * -
  1622. *
  1623. * CHANGES
  1624. *
  1625. * -
  1626. *
  1627. ******************************************************************************/
  1628. static void Transform_Bicubic_Patch(OBJECT *Object, TRANSFORM *Trans)
  1629. {
  1630. int i, j;
  1631. BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  1632. for (i = 0; i < 4; i++)
  1633. {
  1634. for (j = 0; j < 4; j++)
  1635. {
  1636. MTransPoint(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Trans);
  1637. }
  1638. }
  1639. Precompute_Patch_Values(Patch);
  1640. Compute_Bicubic_Patch_BBox(Patch);
  1641. }
  1642. /*****************************************************************************
  1643. *
  1644. * FUNCTION
  1645. *
  1646. * Invert_Bicubic_Patch
  1647. *
  1648. * INPUT
  1649. *
  1650. * OUTPUT
  1651. *
  1652. * RETURNS
  1653. *
  1654. * AUTHOR
  1655. *
  1656. * Alexander Enzmann
  1657. *
  1658. * DESCRIPTION
  1659. *
  1660. * Inversion of a patch really doesn't make sense.
  1661. *
  1662. * CHANGES
  1663. *
  1664. * -
  1665. *
  1666. ******************************************************************************/
  1667. static void Invert_Bicubic_Patch(OBJECT *Object)
  1668. {
  1669. }
  1670. /*****************************************************************************
  1671. *
  1672. * FUNCTION
  1673. *
  1674. * Create_Bicubic_Patch
  1675. *
  1676. * INPUT
  1677. *
  1678. * OUTPUT
  1679. *
  1680. * RETURNS
  1681. *
  1682. * AUTHOR
  1683. *
  1684. * Alexander Enzmann
  1685. *
  1686. * DESCRIPTION
  1687. *
  1688. * -
  1689. *
  1690. * CHANGES
  1691. *
  1692. * -
  1693. *
  1694. ******************************************************************************/
  1695. BICUBIC_PATCH *Create_Bicubic_Patch()
  1696. {
  1697. BICUBIC_PATCH *New;
  1698. New = (BICUBIC_PATCH *)POV_MALLOC(sizeof (BICUBIC_PATCH), "bicubic patch");
  1699. INIT_OBJECT_FIELDS(New, BICUBIC_PATCH_OBJECT, &Bicubic_Patch_Methods)
  1700. New->Patch_Type = - 1;
  1701. New->U_Steps = 0;
  1702. New->V_Steps = 0;
  1703. New->Flatness_Value = 0.0;
  1704. New->Node_Tree = NULL;
  1705. /*
  1706. * NOTE: Control_Points[4][4] is initialized in Parse_Bicubic_Patch.
  1707. * Bounding_Sphere_Center,Bounding_Sphere_Radius, Normal_Vector[], and
  1708. * IPoint[] are initialized in Precompute_Patch_Values.
  1709. */
  1710. return (New);
  1711. }
  1712. /*****************************************************************************
  1713. *
  1714. * FUNCTION
  1715. *
  1716. * Copy_Bicubic_Patch
  1717. *
  1718. * INPUT
  1719. *
  1720. * OUTPUT
  1721. *
  1722. * RETURNS
  1723. *
  1724. * AUTHOR
  1725. *
  1726. * Alexander Enzmann
  1727. *
  1728. * DESCRIPTION
  1729. *
  1730. * -
  1731. *
  1732. * CHANGES
  1733. *
  1734. * -
  1735. *
  1736. ******************************************************************************/
  1737. static BICUBIC_PATCH *Copy_Bicubic_Patch(OBJECT *Object)
  1738. {
  1739. int i, j;
  1740. BICUBIC_PATCH *New;
  1741. New = Create_Bicubic_Patch();
  1742. /* Do not do *New = *Old so that Precompute works right */
  1743. New->Patch_Type = ((BICUBIC_PATCH *)Object)->Patch_Type;
  1744. New->U_Steps = ((BICUBIC_PATCH *)Object)->U_Steps;
  1745. New->V_Steps = ((BICUBIC_PATCH *)Object)->V_Steps;
  1746. for (i = 0; i < 4; i++)
  1747. {
  1748. for (j = 0; j < 4; j++)
  1749. {
  1750. Assign_Vector(New->Control_Points[i][j], ((BICUBIC_PATCH *)Object)->Control_Points[i][j]);
  1751. }
  1752. }
  1753. New->Flatness_Value = ((BICUBIC_PATCH *)Object)->Flatness_Value;
  1754. Precompute_Patch_Values(New);
  1755. return (New);
  1756. }
  1757. /*****************************************************************************
  1758. *
  1759. * FUNCTION
  1760. *
  1761. * Destroy_Bicubic_Patch
  1762. *
  1763. * INPUT
  1764. *
  1765. * OUTPUT
  1766. *
  1767. * RETURNS
  1768. *
  1769. * AUTHOR
  1770. *
  1771. * Alexander Enzmann
  1772. *
  1773. * DESCRIPTION
  1774. *
  1775. * -
  1776. *
  1777. * CHANGES
  1778. *
  1779. * -
  1780. *
  1781. ******************************************************************************/
  1782. static void Destroy_Bicubic_Patch(OBJECT *Object)
  1783. {
  1784. BICUBIC_PATCH *Patch;
  1785. Patch = (BICUBIC_PATCH *)Object;
  1786. if (Patch->Patch_Type != 0)
  1787. {
  1788. if (Patch->Node_Tree != NULL)
  1789. {
  1790. bezier_tree_deleter(Patch->Node_Tree);
  1791. }
  1792. }
  1793. POV_FREE(Patch);
  1794. }
  1795. /*****************************************************************************
  1796. *
  1797. * FUNCTION
  1798. *
  1799. * Compute_Bicubic_Patch_BBox
  1800. *
  1801. * INPUT
  1802. *
  1803. * Bicubic_Patch - Bicubic patch
  1804. *
  1805. * OUTPUT
  1806. *
  1807. * Bicubic_Patch
  1808. *
  1809. * RETURNS
  1810. *
  1811. * AUTHOR
  1812. *
  1813. * Dieter Bayer
  1814. *
  1815. * DESCRIPTION
  1816. *
  1817. * Calculate the bounding box of a bicubic patch.
  1818. *
  1819. * CHANGES
  1820. *
  1821. * Aug 1994 : Creation.
  1822. *
  1823. ******************************************************************************/
  1824. void Compute_Bicubic_Patch_BBox(BICUBIC_PATCH *Bicubic_Patch)
  1825. {
  1826. int i, j;
  1827. VECTOR Min, Max;
  1828. Make_Vector(Min, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  1829. Make_Vector(Max, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  1830. for (i = 0; i < 4; i++)
  1831. {
  1832. for (j = 0; j < 4; j++)
  1833. {
  1834. Min[X] = min(Min[X], Bicubic_Patch->Control_Points[i][j][X]);
  1835. Min[Y] = min(Min[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  1836. Min[Z] = min(Min[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  1837. Max[X] = max(Max[X], Bicubic_Patch->Control_Points[i][j][X]);
  1838. Max[Y] = max(Max[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  1839. Max[Z] = max(Max[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  1840. }
  1841. }
  1842. Make_BBox_from_min_max(Bicubic_Patch->BBox, Min, Max);
  1843. }