Export_3ds: Improved distance cue node search
[blender-addons.git] / render_povray / model_curve_topology.py
blob38061083dacc803019d0a09983a41ee0bd948585
1 # SPDX-FileCopyrightText: 2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 """Translate to POV the control point compounded geometries like polygon
7 meshes or curve based shapes.
8 """
10 import bpy
13 # -------- LOFT, ETC.
16 def export_curves(file, ob, tab_write):
17 """write all curves based POV primitives to exported file
19 Args:
20 file: The POV file being written
21 ob: The current curve object to export from Blender
22 string_strip_hyphen: Function to clean up names
23 tab_write: Function to write to POV file
24 """
25 from .shading import write_object_material_interior
26 from .render import string_strip_hyphen
28 # name_orig = "OB" + ob.name # XXX Unused, check instantiation
29 dataname_orig = "DATA" + ob.data.name
31 # name = string_strip_hyphen(bpy.path.clean_name(name_orig)) # XXX Unused, check instantiation
32 dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))
34 # matrix = global_matrix @ ob.matrix_world # XXX Unused, check instantiation
35 bezier_sweep = False
36 if ob.pov.curveshape == "sphere_sweep":
37 # TODO: Check radius ; shorten lines, may use tab_write() ? > fstrings since py 2.9
38 # inlined spheresweep macro, which itself calls Shapes.inc:
39 file.write(' #include "shapes.inc"\n')
41 file.write(
42 " #macro Shape_Bezierpoints_Sphere_Sweep(_merge_shape, _resolution, _points_array, _radius_array)\n"
44 file.write(" //input adjusting and inspection\n")
45 file.write(" #if(_resolution <= 1)\n")
46 file.write(" #local res = 1;\n")
47 file.write(" #else\n")
48 file.write(" #local res = int(_resolution);\n")
49 file.write(" #end\n")
50 file.write(" #if(dimensions(_points_array) != 1 | dimensions(_radius_array) != 1)\n")
51 file.write(' #error ""\n')
52 file.write(
53 " #elseif(div(dimension_size(_points_array,1),4) - dimension_size(_points_array,1)/4 != 0)\n"
55 file.write(' #error ""\n')
56 file.write(
57 " #elseif(dimension_size(_points_array,1) != dimension_size(_radius_array,1))\n"
59 file.write(' #error ""\n')
60 file.write(" #else\n")
61 file.write(" #local n_of_seg = div(dimension_size(_points_array,1), 4);\n")
62 file.write(" #local ctrl_pts_array = array[n_of_seg]\n")
63 file.write(" #local ctrl_rs_array = array[n_of_seg]\n")
64 file.write(" #for(i, 0, n_of_seg-1)\n")
65 file.write(
66 " #local ctrl_pts_array[i] = array[4] {_points_array[4*i], _points_array[4*i+1], _points_array[4*i+2], _points_array[4*i+3]}\n"
68 file.write(
69 " #local ctrl_rs_array[i] = array[4] {abs(_radius_array[4*i]), abs(_radius_array[4*i+1]), abs(_radius_array[4*i+2]), abs(_radius_array[4*i+3])}\n"
71 file.write(" #end\n")
72 file.write(" #end\n")
74 file.write(" //drawing\n")
75 file.write(" #local mockup1 =\n")
76 file.write(" #if(_merge_shape) merge{ #else union{ #end\n")
77 file.write(" #for(i, 0, n_of_seg-1)\n")
78 file.write(" #local has_head = true;\n")
79 file.write(" #if(i = 0)\n")
80 file.write(
81 " #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[n_of_seg-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[n_of_seg-1][3] <= 0)\n"
83 file.write(" #local has_head = false;\n")
84 file.write(" #end\n")
85 file.write(" #else\n")
86 file.write(
87 " #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[i-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[i-1][3] <= 0)\n"
89 file.write(" #local has_head = false;\n")
90 file.write(" #end\n")
91 file.write(" #end\n")
92 file.write(" #if(has_head = true)\n")
93 file.write(" sphere{\n")
94 file.write(" ctrl_pts_array[i][0], ctrl_rs_array[i][0]\n")
95 file.write(" }\n")
96 file.write(" #end\n")
97 file.write(" #local para_t = (1/2)/res;\n")
98 file.write(
99 " #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n"
101 file.write(
102 " #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n"
104 file.write(
105 " #if(vlength(this_point-ctrl_pts_array[i][0]) > abs(this_radius-ctrl_rs_array[i][0]))\n"
107 file.write(" object{\n")
108 file.write(
109 " Connect_Spheres(ctrl_pts_array[i][0], ctrl_rs_array[i][0], this_point, this_radius)\n"
111 file.write(" }\n")
112 file.write(" #end\n")
113 file.write(" sphere{\n")
114 file.write(" this_point, this_radius\n")
115 file.write(" }\n")
116 file.write(" #for(j, 1, res-1)\n")
117 file.write(" #local last_point = this_point;\n")
118 file.write(" #local last_radius = this_radius;\n")
119 file.write(" #local para_t = (1/2+j)/res;\n")
120 file.write(
121 " #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n"
123 file.write(
124 " #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n"
126 file.write(
127 " #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n"
129 file.write(" object{\n")
130 file.write(
131 " Connect_Spheres(last_point, last_radius, this_point, this_radius)\n"
133 file.write(" }\n")
134 file.write(" #end\n")
135 file.write(" sphere{\n")
136 file.write(" this_point, this_radius\n")
137 file.write(" }\n")
138 file.write(" #end\n")
139 file.write(" #local last_point = this_point;\n")
140 file.write(" #local last_radius = this_radius;\n")
141 file.write(" #local this_point = ctrl_pts_array[i][3];\n")
142 file.write(" #local this_radius = ctrl_rs_array[i][3];\n")
143 file.write(
144 " #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n"
146 file.write(" object{\n")
147 file.write(
148 " Connect_Spheres(last_point, last_radius, this_point, this_radius)\n"
150 file.write(" }\n")
151 file.write(" #end\n")
152 file.write(" sphere{\n")
153 file.write(" this_point, this_radius\n")
154 file.write(" }\n")
155 file.write(" #end\n")
156 file.write(" }\n")
157 file.write(" mockup1\n")
158 file.write(" #end\n")
160 for spl in ob.data.splines:
161 if spl.type == "BEZIER":
162 bezier_sweep = True
163 if ob.pov.curveshape in ("loft", "birail"):
164 n = 0
165 for spline in ob.data.splines:
166 n += 1
167 tab_write(file, "#declare %s%s=spline {\n" % (dataname, n))
168 tab_write(file, "cubic_spline\n")
169 lp = len(spline.points)
170 delta = 1 / lp
171 d = -delta
172 point = spline.points[lp - 1]
173 x, y, z, w = point.co[:]
174 tab_write(file, "%.6f, <%.6f,%.6f,%.6f>\n" % (d, x, y, z))
175 d += delta
176 for point in spline.points:
177 x, y, z, w = point.co[:]
178 tab_write(file, "%.6f, <%.6f,%.6f,%.6f>\n" % (d, x, y, z))
179 d += delta
180 for i in range(2):
181 point = spline.points[i]
182 x, y, z, w = point.co[:]
183 tab_write(file, "%.6f, <%.6f,%.6f,%.6f>\n" % (d, x, y, z))
184 d += delta
185 tab_write(file, "}\n")
186 if ob.pov.curveshape == "loft":
187 n = len(ob.data.splines)
188 tab_write(file, "#declare %s = array[%s]{\n" % (dataname, (n + 3)))
189 tab_write(file, "spline{%s%s},\n" % (dataname, n))
190 for i in range(n):
191 tab_write(file, "spline{%s%s},\n" % (dataname, (i + 1)))
192 tab_write(file, "spline{%s1},\n" % dataname)
193 tab_write(file, "spline{%s2}\n" % dataname)
194 tab_write(file, "}\n")
195 # Use some of the Meshmaker.inc macro, here inlined
196 file.write("#macro CheckFileName(FileName)\n")
197 file.write(" #local Len=strlen(FileName);\n")
198 file.write(" #if(Len>0)\n")
199 file.write(" #if(file_exists(FileName))\n")
200 file.write(" #if(Len>=4)\n")
201 file.write(" #local Ext=strlwr(substr(FileName,Len-3,4))\n")
202 file.write(
203 ' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n'
205 file.write(" #local Return=99;\n")
206 file.write(" #else\n")
207 file.write(" #local Return=0;\n")
208 file.write(" #end\n")
209 file.write(" #else\n")
210 file.write(" #local Return=0;\n")
211 file.write(" #end\n")
212 file.write(" #else\n")
213 file.write(" #if(Len>=4)\n")
214 file.write(" #local Ext=strlwr(substr(FileName,Len-3,4))\n")
215 file.write(
216 ' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n'
218 file.write(' #if (strcmp(Ext,".obj")=0)\n')
219 file.write(" #local Return=2;\n")
220 file.write(" #end\n")
221 file.write(' #if (strcmp(Ext,".pcm")=0)\n')
222 file.write(" #local Return=3;\n")
223 file.write(" #end\n")
224 file.write(' #if (strcmp(Ext,".arr")=0)\n')
225 file.write(" #local Return=4;\n")
226 file.write(" #end\n")
227 file.write(" #else\n")
228 file.write(" #local Return=1;\n")
229 file.write(" #end\n")
230 file.write(" #else\n")
231 file.write(" #local Return=1;\n")
232 file.write(" #end\n")
233 file.write(" #end\n")
234 file.write(" #else\n")
235 file.write(" #local Return=1;\n")
236 file.write(" #end\n")
237 file.write(" (Return)\n")
238 file.write("#end\n")
240 file.write("#macro BuildSpline(Arr, SplType)\n")
241 file.write(" #local Ds=dimension_size(Arr,1);\n")
242 file.write(" #local Asc=asc(strupr(SplType));\n")
243 file.write(" #if(Asc!=67 & Asc!=76 & Asc!=81) \n")
244 file.write(" #local Asc=76;\n")
245 file.write(
246 ' #debug "\nWrong spline type defined (C/c/L/l/N/n/Q/q), using default linear_spline\\n"\n'
248 file.write(" #end\n")
249 file.write(" spline {\n")
250 file.write(" #switch (Asc)\n")
251 file.write(" #case (67) //C cubic_spline\n")
252 file.write(" cubic_spline\n")
253 file.write(" #break\n")
254 file.write(" #case (76) //L linear_spline\n")
255 file.write(" linear_spline\n")
256 file.write(" #break\n")
257 file.write(" #case (78) //N linear_spline\n")
258 file.write(" natural_spline\n")
259 file.write(" #break\n")
260 file.write(" #case (81) //Q Quadratic_spline\n")
261 file.write(" quadratic_spline\n")
262 file.write(" #break\n")
263 file.write(" #end\n")
264 file.write(" #local Add=1/((Ds-2)-1);\n")
265 file.write(" #local J=0-Add;\n")
266 file.write(" #local I=0;\n")
267 file.write(" #while (I<Ds)\n")
268 file.write(" J\n")
269 file.write(" Arr[I]\n")
270 file.write(" #local I=I+1;\n")
271 file.write(" #local J=J+Add;\n")
272 file.write(" #end\n")
273 file.write(" }\n")
274 file.write("#end\n")
276 file.write("#macro BuildWriteMesh2(VecArr, NormArr, UVArr, U, V, FileName)\n")
277 # suppressed some file checking from original macro because no more separate files
278 file.write(" #local Write=0;\n")
279 file.write(' #debug concat("\\n\\n Building mesh2: \\n - vertex_vectors\\n")\n')
280 file.write(" #local NumVertices=dimension_size(VecArr,1);\n")
281 file.write(" #switch (Write)\n")
282 file.write(" #case(1)\n")
283 file.write(" #write(\n")
284 file.write(" MeshFile,\n")
285 file.write(' " vertex_vectors {\\n",\n')
286 file.write(' " ", str(NumVertices,0,0),"\\n "\n')
287 file.write(" )\n")
288 file.write(" #break\n")
289 file.write(" #case(2)\n")
290 file.write(" #write(\n")
291 file.write(" MeshFile,\n")
292 file.write(' "# Vertices: ",str(NumVertices,0,0),"\\n"\n')
293 file.write(" )\n")
294 file.write(" #break\n")
295 file.write(" #case(3)\n")
296 file.write(" #write(\n")
297 file.write(" MeshFile,\n")
298 file.write(' str(2*NumVertices,0,0),",\\n"\n')
299 file.write(" )\n")
300 file.write(" #break\n")
301 file.write(" #case(4)\n")
302 file.write(" #write(\n")
303 file.write(" MeshFile,\n")
304 file.write(' "#declare VertexVectors= array[",str(NumVertices,0,0),"] {\\n "\n')
305 file.write(" )\n")
306 file.write(" #break\n")
307 file.write(" #end\n")
308 file.write(" mesh2 {\n")
309 file.write(" vertex_vectors {\n")
310 file.write(" NumVertices\n")
311 file.write(" #local I=0;\n")
312 file.write(" #while (I<NumVertices)\n")
313 file.write(" VecArr[I]\n")
314 file.write(" #switch(Write)\n")
315 file.write(" #case(1)\n")
316 file.write(" #write(MeshFile, VecArr[I])\n")
317 file.write(" #break\n")
318 file.write(" #case(2)\n")
319 file.write(" #write(\n")
320 file.write(" MeshFile,\n")
321 file.write(
322 ' "v ", VecArr[I].x," ", VecArr[I].y," ", VecArr[I].z,"\\n"\n'
324 file.write(" )\n")
325 file.write(" #break\n")
326 file.write(" #case(3)\n")
327 file.write(" #write(\n")
328 file.write(" MeshFile,\n")
329 file.write(' VecArr[I].x,",", VecArr[I].y,",", VecArr[I].z,",\\n"\n')
330 file.write(" )\n")
331 file.write(" #break\n")
332 file.write(" #case(4)\n")
333 file.write(" #write(MeshFile, VecArr[I])\n")
334 file.write(" #break\n")
335 file.write(" #end\n")
336 file.write(" #local I=I+1;\n")
337 file.write(" #if(Write=1 | Write=4)\n")
338 file.write(" #if(mod(I,3)=0)\n")
339 file.write(' #write(MeshFile,"\\n ")\n')
340 file.write(" #end\n")
341 file.write(" #end \n")
342 file.write(" #end\n")
343 file.write(" #switch(Write)\n")
344 file.write(" #case(1)\n")
345 file.write(' #write(MeshFile,"\\n }\\n")\n')
346 file.write(" #break\n")
347 file.write(" #case(2)\n")
348 file.write(' #write(MeshFile,"\\n")\n')
349 file.write(" #break\n")
350 file.write(" #case(3)\n")
351 file.write(" // do nothing\n")
352 file.write(" #break\n")
353 file.write(" #case(4) \n")
354 file.write(' #write(MeshFile,"\\n}\\n")\n')
355 file.write(" #break\n")
356 file.write(" #end\n")
357 file.write(" }\n")
359 file.write(' #debug concat(" - normal_vectors\\n") \n')
360 file.write(" #local NumVertices=dimension_size(NormArr,1);\n")
361 file.write(" #switch(Write)\n")
362 file.write(" #case(1)\n")
363 file.write(" #write(\n")
364 file.write(" MeshFile,\n")
365 file.write(' " normal_vectors {\\n",\n')
366 file.write(' " ", str(NumVertices,0,0),"\\n "\n')
367 file.write(" )\n")
368 file.write(" #break\n")
369 file.write(" #case(2)\n")
370 file.write(" #write(\n")
371 file.write(" MeshFile,\n")
372 file.write(' "# Normals: ",str(NumVertices,0,0),"\\n"\n')
373 file.write(" )\n")
374 file.write(" #break\n")
375 file.write(" #case(3)\n")
376 file.write(" // do nothing\n")
377 file.write(" #break\n")
378 file.write(" #case(4)\n")
379 file.write(" #write(\n")
380 file.write(" MeshFile,\n")
381 file.write(
382 ' "#declare NormalVectors= array[",str(NumVertices,0,0),"] {\\n "\n'
384 file.write(" )\n")
385 file.write(" #break\n")
386 file.write(" #end\n")
387 file.write(" normal_vectors {\n")
388 file.write(" NumVertices\n")
389 file.write(" #local I=0;\n")
390 file.write(" #while (I<NumVertices)\n")
391 file.write(" NormArr[I]\n")
392 file.write(" #switch(Write)\n")
393 file.write(" #case(1)\n")
394 file.write(" #write(MeshFile NormArr[I])\n")
395 file.write(" #break\n")
396 file.write(" #case(2)\n")
397 file.write(" #write(\n")
398 file.write(" MeshFile,\n")
399 file.write(
400 ' "vn ", NormArr[I].x," ", NormArr[I].y," ", NormArr[I].z,"\\n"\n'
402 file.write(" )\n")
403 file.write(" #break\n")
404 file.write(" #case(3)\n")
405 file.write(" #write(\n")
406 file.write(" MeshFile,\n")
407 file.write(' NormArr[I].x,",", NormArr[I].y,",", NormArr[I].z,",\\n"\n')
408 file.write(" )\n")
409 file.write(" #break\n")
410 file.write(" #case(4)\n")
411 file.write(" #write(MeshFile NormArr[I])\n")
412 file.write(" #break\n")
413 file.write(" #end\n")
414 file.write(" #local I=I+1;\n")
415 file.write(" #if(Write=1 | Write=4) \n")
416 file.write(" #if(mod(I,3)=0)\n")
417 file.write(' #write(MeshFile,"\\n ")\n')
418 file.write(" #end\n")
419 file.write(" #end\n")
420 file.write(" #end\n")
421 file.write(" #switch(Write)\n")
422 file.write(" #case(1)\n")
423 file.write(' #write(MeshFile,"\\n }\\n")\n')
424 file.write(" #break\n")
425 file.write(" #case(2)\n")
426 file.write(' #write(MeshFile,"\\n")\n')
427 file.write(" #break\n")
428 file.write(" #case(3)\n")
429 file.write(" //do nothing\n")
430 file.write(" #break\n")
431 file.write(" #case(4)\n")
432 file.write(' #write(MeshFile,"\\n}\\n")\n')
433 file.write(" #break\n")
434 file.write(" #end\n")
435 file.write(" }\n")
437 file.write(' #debug concat(" - uv_vectors\\n") \n')
438 file.write(" #local NumVertices=dimension_size(UVArr,1);\n")
439 file.write(" #switch(Write)\n")
440 file.write(" #case(1)\n")
441 file.write(" #write(\n")
442 file.write(" MeshFile, \n")
443 file.write(' " uv_vectors {\\n",\n')
444 file.write(' " ", str(NumVertices,0,0),"\\n "\n')
445 file.write(" )\n")
446 file.write(" #break\n")
447 file.write(" #case(2)\n")
448 file.write(" #write(\n")
449 file.write(" MeshFile,\n")
450 file.write(' "# UV-vectors: ",str(NumVertices,0,0),"\\n"\n')
451 file.write(" )\n")
452 file.write(" #break\n")
453 file.write(" #case(3)\n")
454 file.write(" // do nothing, *.pcm does not support uv-vectors\n")
455 file.write(" #break\n")
456 file.write(" #case(4)\n")
457 file.write(" #write(\n")
458 file.write(" MeshFile,\n")
459 file.write(' "#declare UVVectors= array[",str(NumVertices,0,0),"] {\\n "\n')
460 file.write(" )\n")
461 file.write(" #break\n")
462 file.write(" #end\n")
463 file.write(" uv_vectors {\n")
464 file.write(" NumVertices\n")
465 file.write(" #local I=0;\n")
466 file.write(" #while (I<NumVertices)\n")
467 file.write(" UVArr[I]\n")
468 file.write(" #switch(Write)\n")
469 file.write(" #case(1)\n")
470 file.write(" #write(MeshFile UVArr[I])\n")
471 file.write(" #break\n")
472 file.write(" #case(2)\n")
473 file.write(" #write(\n")
474 file.write(" MeshFile,\n")
475 file.write(' "vt ", UVArr[I].u," ", UVArr[I].v,"\\n"\n')
476 file.write(" )\n")
477 file.write(" #break\n")
478 file.write(" #case(3)\n")
479 file.write(" //do nothing\n")
480 file.write(" #break\n")
481 file.write(" #case(4)\n")
482 file.write(" #write(MeshFile UVArr[I])\n")
483 file.write(" #break\n")
484 file.write(" #end\n")
485 file.write(" #local I=I+1; \n")
486 file.write(" #if(Write=1 | Write=4)\n")
487 file.write(" #if(mod(I,3)=0)\n")
488 file.write(' #write(MeshFile,"\\n ")\n')
489 file.write(" #end \n")
490 file.write(" #end\n")
491 file.write(" #end \n")
492 file.write(" #switch(Write)\n")
493 file.write(" #case(1)\n")
494 file.write(' #write(MeshFile,"\\n }\\n")\n')
495 file.write(" #break\n")
496 file.write(" #case(2)\n")
497 file.write(' #write(MeshFile,"\\n")\n')
498 file.write(" #break\n")
499 file.write(" #case(3)\n")
500 file.write(" //do nothing\n")
501 file.write(" #break\n")
502 file.write(" #case(4)\n")
503 file.write(' #write(MeshFile,"\\n}\\n")\n')
504 file.write(" #break\n")
505 file.write(" #end\n")
506 file.write(" }\n")
507 file.write("\n")
508 file.write(' #debug concat(" - face_indices\\n") \n')
509 file.write(" #declare NumFaces=U*V*2;\n")
510 file.write(" #switch(Write)\n")
511 file.write(" #case(1)\n")
512 file.write(" #write(\n")
513 file.write(" MeshFile,\n")
514 file.write(' " face_indices {\\n"\n')
515 file.write(' " ", str(NumFaces,0,0),"\\n "\n')
516 file.write(" )\n")
517 file.write(" #break\n")
518 file.write(" #case(2)\n")
519 file.write(" #write (\n")
520 file.write(" MeshFile,\n")
521 file.write(' "# faces: ",str(NumFaces,0,0),"\\n"\n')
522 file.write(" )\n")
523 file.write(" #break\n")
524 file.write(" #case(3)\n")
525 file.write(" #write (\n")
526 file.write(" MeshFile,\n")
527 file.write(' "0,",str(NumFaces,0,0),",\\n"\n')
528 file.write(" )\n")
529 file.write(" #break\n")
530 file.write(" #case(4)\n")
531 file.write(" #write(\n")
532 file.write(" MeshFile,\n")
533 file.write(' "#declare FaceIndices= array[",str(NumFaces,0,0),"] {\\n "\n')
534 file.write(" )\n")
535 file.write(" #break\n")
536 file.write(" #end\n")
537 file.write(" face_indices {\n")
538 file.write(" NumFaces\n")
539 file.write(" #local I=0;\n")
540 file.write(" #local H=0;\n")
541 file.write(" #local NumVertices=dimension_size(VecArr,1);\n")
542 file.write(" #while (I<V)\n")
543 file.write(" #local J=0;\n")
544 file.write(" #while (J<U)\n")
545 file.write(" #local Ind=(I*U)+I+J;\n")
546 file.write(" <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n")
547 file.write(" #switch(Write)\n")
548 file.write(" #case(1)\n")
549 file.write(" #write(\n")
550 file.write(" MeshFile,\n")
551 file.write(" <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n")
552 file.write(" )\n")
553 file.write(" #break\n")
554 file.write(" #case(2)\n")
555 file.write(" #write(\n")
556 file.write(" MeshFile,\n")
557 file.write(
558 ' "f ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+1+1,"/",Ind+1+1,"/",Ind+1+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n",\n'
560 file.write(
561 ' "f ",Ind+U+1+1,"/",Ind+U+1+1,"/",Ind+U+1+1," ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n"\n'
563 file.write(" )\n")
564 file.write(" #break\n")
565 file.write(" #case(3)\n")
566 file.write(" #write(\n")
567 file.write(" MeshFile,\n")
568 file.write(
569 ' Ind,",",Ind+NumVertices,",",Ind+1,",",Ind+1+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n'
571 file.write(
572 ' Ind+U+1,",",Ind+U+1+NumVertices,",",Ind,",",Ind+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n'
574 file.write(" )\n")
575 file.write(" #break\n")
576 file.write(" #case(4)\n")
577 file.write(" #write(\n")
578 file.write(" MeshFile,\n")
579 file.write(" <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n")
580 file.write(" )\n")
581 file.write(" #break\n")
582 file.write(" #end\n")
583 file.write(" #local J=J+1;\n")
584 file.write(" #local H=H+1;\n")
585 file.write(" #if(Write=1 | Write=4)\n")
586 file.write(" #if(mod(H,3)=0)\n")
587 file.write(' #write(MeshFile,"\\n ")\n')
588 file.write(" #end \n")
589 file.write(" #end\n")
590 file.write(" #end\n")
591 file.write(" #local I=I+1;\n")
592 file.write(" #end\n")
593 file.write(" }\n")
594 file.write(" #switch(Write)\n")
595 file.write(" #case(1)\n")
596 file.write(' #write(MeshFile, "\\n }\\n}")\n')
597 file.write(" #fclose MeshFile\n")
598 file.write(' #debug concat(" Done writing\\n")\n')
599 file.write(" #break\n")
600 file.write(" #case(2)\n")
601 file.write(" #fclose MeshFile\n")
602 file.write(' #debug concat(" Done writing\\n")\n')
603 file.write(" #break\n")
604 file.write(" #case(3)\n")
605 file.write(" #fclose MeshFile\n")
606 file.write(' #debug concat(" Done writing\\n")\n')
607 file.write(" #break\n")
608 file.write(" #case(4)\n")
609 file.write(' #write(MeshFile, "\\n}\\n}")\n')
610 file.write(" #fclose MeshFile\n")
611 file.write(' #debug concat(" Done writing\\n")\n')
612 file.write(" #break\n")
613 file.write(" #end\n")
614 file.write(" }\n")
615 file.write("#end\n")
617 file.write("#macro MSM(SplineArray, SplRes, Interp_type, InterpRes, FileName)\n")
618 file.write(" #declare Build=CheckFileName(FileName);\n")
619 file.write(" #if(Build=0)\n")
620 file.write(' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n')
621 file.write(" #include FileName\n")
622 file.write(" object{Surface}\n")
623 file.write(" #else\n")
624 file.write(" #local NumVertices=(SplRes+1)*(InterpRes+1);\n")
625 file.write(" #local NumFaces=SplRes*InterpRes*2;\n")
626 file.write(
627 ' #debug concat("\\n Calculating ",str(NumVertices,0,0)," vertices for ", str(NumFaces,0,0)," triangles\\n\\n")\n'
629 file.write(" #local VecArr=array[NumVertices]\n")
630 file.write(" #local NormArr=array[NumVertices]\n")
631 file.write(" #local UVArr=array[NumVertices]\n")
632 file.write(" #local N=dimension_size(SplineArray,1);\n")
633 file.write(" #local TempSplArr0=array[N];\n")
634 file.write(" #local TempSplArr1=array[N];\n")
635 file.write(" #local TempSplArr2=array[N];\n")
636 file.write(" #local PosStep=1/SplRes;\n")
637 file.write(" #local InterpStep=1/InterpRes;\n")
638 file.write(" #local Count=0;\n")
639 file.write(" #local Pos=0;\n")
640 file.write(" #while(Pos<=1)\n")
641 file.write(" #local I=0;\n")
642 file.write(" #if (Pos=0)\n")
643 file.write(" #while (I<N)\n")
644 file.write(" #local Spl=spline{SplineArray[I]}\n")
645 file.write(" #local TempSplArr0[I]=<0,0,0>+Spl(Pos);\n")
646 file.write(" #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n")
647 file.write(" #local TempSplArr2[I]=<0,0,0>+Spl(Pos-PosStep);\n")
648 file.write(" #local I=I+1;\n")
649 file.write(" #end\n")
650 file.write(" #local S0=BuildSpline(TempSplArr0, Interp_type)\n")
651 file.write(" #local S1=BuildSpline(TempSplArr1, Interp_type)\n")
652 file.write(" #local S2=BuildSpline(TempSplArr2, Interp_type)\n")
653 file.write(" #else\n")
654 file.write(" #while (I<N)\n")
655 file.write(" #local Spl=spline{SplineArray[I]}\n")
656 file.write(" #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n")
657 file.write(" #local I=I+1;\n")
658 file.write(" #end\n")
659 file.write(" #local S1=BuildSpline(TempSplArr1, Interp_type)\n")
660 file.write(" #end\n")
661 file.write(" #local J=0;\n")
662 file.write(" #while (J<=1)\n")
663 file.write(" #local P0=<0,0,0>+S0(J);\n")
664 file.write(" #local P1=<0,0,0>+S1(J);\n")
665 file.write(" #local P2=<0,0,0>+S2(J);\n")
666 file.write(" #local P3=<0,0,0>+S0(J+InterpStep);\n")
667 file.write(" #local P4=<0,0,0>+S0(J-InterpStep);\n")
668 file.write(" #local B1=P4-P0;\n")
669 file.write(" #local B2=P2-P0;\n")
670 file.write(" #local B3=P3-P0;\n")
671 file.write(" #local B4=P1-P0;\n")
672 file.write(" #local N1=vcross(B1,B2);\n")
673 file.write(" #local N2=vcross(B2,B3);\n")
674 file.write(" #local N3=vcross(B3,B4);\n")
675 file.write(" #local N4=vcross(B4,B1);\n")
676 file.write(" #local Norm=vnormalize((N1+N2+N3+N4));\n")
677 file.write(" #local VecArr[Count]=P0;\n")
678 file.write(" #local NormArr[Count]=Norm;\n")
679 file.write(" #local UVArr[Count]=<J,Pos>;\n")
680 file.write(" #local J=J+InterpStep;\n")
681 file.write(" #local Count=Count+1;\n")
682 file.write(" #end\n")
683 file.write(" #local S2=spline{S0}\n")
684 file.write(" #local S0=spline{S1}\n")
685 file.write(
686 ' #debug concat("\\r Done ", str(Count,0,0)," vertices : ", str(100*Count/NumVertices,0,2)," %")\n'
688 file.write(" #local Pos=Pos+PosStep;\n")
689 file.write(" #end\n")
690 file.write(' BuildWriteMesh2(VecArr, NormArr, UVArr, InterpRes, SplRes, "")\n')
691 file.write(" #end\n")
692 file.write("#end\n\n")
694 file.write("#macro Coons(Spl1, Spl2, Spl3, Spl4, Iter_U, Iter_V, FileName)\n")
695 file.write(" #declare Build=CheckFileName(FileName);\n")
696 file.write(" #if(Build=0)\n")
697 file.write(' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n')
698 file.write(" #include FileName\n")
699 file.write(" object{Surface}\n")
700 file.write(" #else\n")
701 file.write(" #local NumVertices=(Iter_U+1)*(Iter_V+1);\n")
702 file.write(" #local NumFaces=Iter_U*Iter_V*2;\n")
703 file.write(
704 ' #debug concat("\\n Calculating ", str(NumVertices,0,0), " vertices for ",str(NumFaces,0,0), " triangles\\n\\n")\n'
706 file.write(" #declare VecArr=array[NumVertices] \n")
707 file.write(" #declare NormArr=array[NumVertices] \n")
708 file.write(" #local UVArr=array[NumVertices] \n")
709 file.write(" #local Spl1_0=Spl1(0);\n")
710 file.write(" #local Spl2_0=Spl2(0);\n")
711 file.write(" #local Spl3_0=Spl3(0);\n")
712 file.write(" #local Spl4_0=Spl4(0);\n")
713 file.write(" #local UStep=1/Iter_U;\n")
714 file.write(" #local VStep=1/Iter_V;\n")
715 file.write(" #local Count=0;\n")
716 file.write(" #local I=0;\n")
717 file.write(" #while (I<=1)\n")
718 file.write(" #local Im=1-I;\n")
719 file.write(" #local J=0;\n")
720 file.write(" #while (J<=1)\n")
721 file.write(" #local Jm=1-J;\n")
722 file.write(
723 " #local C0=Im*Jm*(Spl1_0)+Im*J*(Spl2_0)+I*J*(Spl3_0)+I*Jm*(Spl4_0);\n"
725 file.write(" #local P0=LInterpolate(I, Spl1(J), Spl3(Jm)) + \n")
726 file.write(" LInterpolate(Jm, Spl2(I), Spl4(Im))-C0;\n")
727 file.write(" #declare VecArr[Count]=P0;\n")
728 file.write(" #local UVArr[Count]=<J,I>;\n")
729 file.write(" #local J=J+UStep;\n")
730 file.write(" #local Count=Count+1;\n")
731 file.write(" #end\n")
732 file.write(" #debug concat(\n")
733 file.write(' "\r Done ", str(Count,0,0)," vertices : ",\n')
734 file.write(' str(100*Count/NumVertices,0,2)," %"\n')
735 file.write(" )\n")
736 file.write(" #local I=I+VStep;\n")
737 file.write(" #end\n")
738 file.write(' #debug "\r Normals "\n')
739 file.write(" #local Count=0;\n")
740 file.write(" #local I=0;\n")
741 file.write(" #while (I<=Iter_V)\n")
742 file.write(" #local J=0;\n")
743 file.write(" #while (J<=Iter_U)\n")
744 file.write(" #local Ind=(I*Iter_U)+I+J;\n")
745 file.write(" #local P0=VecArr[Ind];\n")
746 file.write(" #if(J=0)\n")
747 file.write(" #local P1=P0+(P0-VecArr[Ind+1]);\n")
748 file.write(" #else\n")
749 file.write(" #local P1=VecArr[Ind-1];\n")
750 file.write(" #end\n")
751 file.write(" #if (J=Iter_U)\n")
752 file.write(" #local P2=P0+(P0-VecArr[Ind-1]);\n")
753 file.write(" #else\n")
754 file.write(" #local P2=VecArr[Ind+1];\n")
755 file.write(" #end\n")
756 file.write(" #if (I=0)\n")
757 file.write(" #local P3=P0+(P0-VecArr[Ind+Iter_U+1]);\n")
758 file.write(" #else\n")
759 file.write(" #local P3=VecArr[Ind-Iter_U-1];\n")
760 file.write(" #end\n")
761 file.write(" #if (I=Iter_V)\n")
762 file.write(" #local P4=P0+(P0-VecArr[Ind-Iter_U-1]);\n")
763 file.write(" #else\n")
764 file.write(" #local P4=VecArr[Ind+Iter_U+1];\n")
765 file.write(" #end\n")
766 file.write(" #local B1=P4-P0;\n")
767 file.write(" #local B2=P2-P0;\n")
768 file.write(" #local B3=P3-P0;\n")
769 file.write(" #local B4=P1-P0;\n")
770 file.write(" #local N1=vcross(B1,B2);\n")
771 file.write(" #local N2=vcross(B2,B3);\n")
772 file.write(" #local N3=vcross(B3,B4);\n")
773 file.write(" #local N4=vcross(B4,B1);\n")
774 file.write(" #local Norm=vnormalize((N1+N2+N3+N4));\n")
775 file.write(" #declare NormArr[Count]=Norm;\n")
776 file.write(" #local J=J+1;\n")
777 file.write(" #local Count=Count+1;\n")
778 file.write(" #end\n")
779 file.write(
780 ' #debug concat("\r Done ", str(Count,0,0)," normals : ",str(100*Count/NumVertices,0,2), " %")\n'
782 file.write(" #local I=I+1;\n")
783 file.write(" #end\n")
784 file.write(" BuildWriteMesh2(VecArr, NormArr, UVArr, Iter_U, Iter_V, FileName)\n")
785 file.write(" #end\n")
786 file.write("#end\n\n")
787 # Empty curves
788 if len(ob.data.splines) == 0:
789 tab_write(file, "\n//dummy sphere to represent empty curve location\n")
790 tab_write(file, "#declare %s =\n" % dataname)
791 tab_write(
792 file,
793 "sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} "
794 "no_image no_reflection no_radiosity "
795 "photons{pass_through collect off} hollow}\n\n"
796 % (ob.location.x, ob.location.y, ob.location.z),
797 ) # ob.name > povdataname)
798 # And non empty curves
799 else:
800 if not bezier_sweep:
801 tab_write(file, "#declare %s =\n" % dataname)
802 if ob.pov.curveshape == "sphere_sweep" and not bezier_sweep:
803 tab_write(file, "union {\n")
804 for spl in ob.data.splines:
805 if spl.type != "BEZIER":
806 spl_type = "linear"
807 if spl.type == "NURBS":
808 spl_type = "cubic"
809 points = spl.points
810 num_points = len(points)
811 if spl.use_cyclic_u:
812 num_points += 3
814 tab_write(file, "sphere_sweep { %s_spline %s,\n" % (spl_type, num_points))
815 if spl.use_cyclic_u:
816 pt1 = points[len(points) - 1]
817 wpt1 = pt1.co
818 tab_write(
819 file,
820 "<%.4g,%.4g,%.4g>,%.4g\n"
822 wpt1[0],
823 wpt1[1],
824 wpt1[2],
825 pt1.radius * ob.data.bevel_depth,
828 for pt in points:
829 wpt = pt.co
830 tab_write(
831 file,
832 "<%.4g,%.4g,%.4g>,%.4g\n"
833 % (wpt[0], wpt[1], wpt[2], pt.radius * ob.data.bevel_depth),
835 if spl.use_cyclic_u:
836 for i in range(0, 2):
837 end_pt = points[i]
838 wpt = end_pt.co
839 tab_write(
840 file,
841 "<%.4g,%.4g,%.4g>,%.4g\n"
843 wpt[0],
844 wpt[1],
845 wpt[2],
846 end_pt.radius * ob.data.bevel_depth,
850 tab_write(file, "}\n")
851 # below not used yet?
852 if ob.pov.curveshape == "sor":
853 for spl in ob.data.splines:
854 if spl.type in ("POLY", "NURBS"):
855 points = spl.points
856 num_points = len(points)
857 tab_write(file, "sor { %s,\n" % num_points)
858 for pt in points:
859 wpt = pt.co
860 tab_write(file, "<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
861 else:
862 tab_write(file, "box { 0,0\n")
863 if ob.pov.curveshape in ("lathe", "prism"):
864 spl = ob.data.splines[0]
865 if spl.type == "BEZIER":
866 points = spl.bezier_points
867 len_cur = len(points) - 1
868 len_pts = len_cur * 4
869 ifprism = ""
870 if ob.pov.curveshape == "prism":
871 height = ob.data.extrude
872 ifprism = "-%s, %s," % (height, height)
873 len_cur += 1
874 len_pts += 4
875 tab_write(
876 file, "%s { bezier_spline %s %s,\n" % (ob.pov.curveshape, ifprism, len_pts)
878 for i in range(0, len_cur):
879 p1 = points[i].co
880 pR = points[i].handle_right
881 end = i + 1
882 if i == len_cur - 1 and ob.pov.curveshape == "prism":
883 end = 0
884 pL = points[end].handle_left
885 p2 = points[end].co
886 line = "<%.4g,%.4g>" % (p1[0], p1[1])
887 line += "<%.4g,%.4g>" % (pR[0], pR[1])
888 line += "<%.4g,%.4g>" % (pL[0], pL[1])
889 line += "<%.4g,%.4g>" % (p2[0], p2[1])
890 tab_write(file, "%s\n" % line)
891 else:
892 points = spl.points
893 len_cur = len(points)
894 len_pts = len_cur
895 ifprism = ""
896 if ob.pov.curveshape == "prism":
897 height = ob.data.extrude
898 ifprism = "-%s, %s," % (height, height)
899 len_pts += 3
900 spl_type = "quadratic"
901 if spl.type == "POLY":
902 spl_type = "linear"
903 tab_write(
904 file,
905 "%s { %s_spline %s %s,\n" % (ob.pov.curveshape, spl_type, ifprism, len_pts),
907 if ob.pov.curveshape == "prism":
908 pt = points[len(points) - 1]
909 wpt = pt.co
910 tab_write(file, "<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
911 for pt in points:
912 wpt = pt.co
913 tab_write(file, "<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
914 if ob.pov.curveshape == "prism":
915 for i in range(2):
916 pt = points[i]
917 wpt = pt.co
918 tab_write(file, "<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
919 if bezier_sweep:
920 for p, spl in enumerate(ob.data.splines, start=1):
921 br = []
922 depth = ob.data.bevel_depth
923 points = spl.bezier_points
924 len_cur = len(points) - 1
925 num_points = len_cur * 4
926 if spl.use_cyclic_u:
927 len_cur += 1
928 num_points += 4
929 tab_write(file, "#declare %s_points_%s = array[%s]{\n" % (dataname, p, num_points))
930 for i in range(len_cur):
931 p1 = points[i].co
932 pR = points[i].handle_right
933 end = i + 1
934 if spl.use_cyclic_u and i == (len_cur - 1):
935 end = 0
936 pL = points[end].handle_left
937 p2 = points[end].co
938 r3 = points[end].radius * depth
939 r0 = points[i].radius * depth
940 r1 = 2 / 3 * r0 + 1 / 3 * r3
941 r2 = 1 / 3 * r0 + 2 / 3 * r3
942 br.append((r0, r1, r2, r3))
943 line = "<%.4g,%.4g,%.4f>" % (p1[0], p1[1], p1[2])
944 line += "<%.4g,%.4g,%.4f>" % (pR[0], pR[1], pR[2])
945 line += "<%.4g,%.4g,%.4f>" % (pL[0], pL[1], pL[2])
946 line += "<%.4g,%.4g,%.4f>" % (p2[0], p2[1], p2[2])
947 tab_write(file, "%s\n" % line)
948 tab_write(file, "}\n")
949 tab_write(file, "#declare %s_radii_%s = array[%s]{\n" % (dataname, p, len(br) * 4))
950 for rad_tuple in br:
951 tab_write(
952 file,
953 "%.4f,%.4f,%.4f,%.4f\n"
954 % (rad_tuple[0], rad_tuple[1], rad_tuple[2], rad_tuple[3]),
956 tab_write(file, "}\n")
957 if len(ob.data.splines) == 1:
958 p = 1
959 tab_write(file, "#declare %s = object{\n" % dataname)
960 tab_write(
961 file,
962 " Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s) \n"
963 % (ob.data.resolution_u, dataname, p, dataname, p),
965 else:
966 tab_write(file, "#declare %s = union{\n" % dataname)
967 for p, spl in enumerate(ob.data.splines, start=1):
968 tab_write(
969 file,
970 " object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s)} \n"
971 % (ob.data.resolution_u, dataname, p, dataname, p),
973 # tab_write(file, '#include "bezier_spheresweep.inc"\n') #now inlined
974 # tab_write(file, '#declare %s = object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_bezier_points, %.4f) \n'%(dataname,ob.data.resolution_u,dataname,ob.data.bevel_depth))
975 if ob.pov.curveshape == "loft":
976 tab_write(
977 file, 'object {MSM(%s,%s,"c",%s,"")\n' % (dataname, ob.pov.res_u, ob.pov.res_v)
979 if ob.pov.curveshape == "birail":
980 splines = "%s1,%s2,%s3,%s4" % (dataname, dataname, dataname, dataname)
981 tab_write(
982 file, 'object {Coons(%s, %s, %s, "")\n' % (splines, ob.pov.res_u, ob.pov.res_v)
984 # pov_mat_name = "Default_texture" # XXX! Unused, check instantiation
985 if ob.active_material:
986 # pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
987 try:
988 material = ob.active_material
989 write_object_material_interior(file, material, ob, tab_write)
990 except IndexError:
991 print(ob.data)
992 # tab_write(file, "texture {%s}\n"%pov_mat_name)
993 if ob.pov.curveshape == "prism":
994 tab_write(file, "rotate <90,0,0>\n")
995 tab_write(file, "scale y*-1\n")
996 tab_write(file, "}\n")