lpdf-u3d.lua /size: 16 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
lpdf-u3d
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to lpdf-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
-- The following code is based on a working prototype provided
10
-- by Michael Vidiassov. It is rewritten using the lpdf library
11
-- and different checking is used. The macro calls are adapted
12
-- (and will eventually be removed). The user interface needs
13
-- an overhaul. There are some messy leftovers that will be
14
-- removed in future versions.
15 16
-- For some reason no one really tested this code so at some
17
-- point we will end up with a reimplementation. For instance
18
-- it makes sense to add the same activation code as with swf.
19 20
local
tonumber
=
tonumber
21
local
formatters
,
find
=
string
.
formatters
,
string
.
find
22
local
cos
,
sin
,
sqrt
,
pi
,
atan2
,
abs
=
math
.
cos
,
math
.
sin
,
math
.
sqrt
,
math
.
pi
,
math
.
atan2
,
math
.
abs
23 24
local
backends
,
lpdf
=
backends
,
lpdf
25 26
local
nodeinjections
=
backends
.
pdf
.
nodeinjections
27 28
local
pdfconstant
=
lpdf
.
constant
29
local
pdfboolean
=
lpdf
.
boolean
30
local
pdfunicode
=
lpdf
.
unicode
31
local
pdfdictionary
=
lpdf
.
dictionary
32
local
pdfarray
=
lpdf
.
array
33
local
pdfnull
=
lpdf
.
null
34
local
pdfreference
=
lpdf
.
reference
35
local
pdfflushstreamobject
=
lpdf
.
flushstreamobject
36
local
pdfflushstreamfileobject
=
lpdf
.
flushstreamfileobject
37 38
local
checkedkey
=
lpdf
.
checkedkey
39
local
limited
=
lpdf
.
limited
40 41
local
embedimage
=
images
.
embed
42 43
local
schemes
=
table
.
tohash
{
44
"
Artwork
"
,
"
None
"
,
"
White
"
,
"
Day
"
,
"
Night
"
,
"
Hard
"
,
45
"
Primary
"
,
"
Blue
"
,
"
Red
"
,
"
Cube
"
,
"
CAD
"
,
"
Headlamp
"
,
46
}
47 48
local
modes
=
table
.
tohash
{
49
"
Solid
"
,
"
SolidWireframe
"
,
"
Transparent
"
,
"
TransparentWireframe
"
,
"
BoundingBox
"
,
50
"
TransparentBoundingBox
"
,
"
TransparentBoundingBoxOutline
"
,
"
Wireframe
"
,
51
"
ShadedWireframe
"
,
"
HiddenWireframe
"
,
"
Vertices
"
,
"
ShadedVertices
"
,
"
Illustration
"
,
52
"
SolidOutline
"
,
"
ShadedIllustration
"
,
53
}
54 55
local
function
normalize
(
x
,
y
,
z
)
56
local
modulo
=
sqrt
(
x
*
x
+
y
*
y
+
z
*
z
)
;
57
if
modulo
~
=
0
then
58
return
x
/
modulo
,
y
/
modulo
,
z
/
modulo
59
else
60
return
x
,
y
,
z
61
end
62
end
63 64
local
function
rotate
(
vect_x
,
vect_y
,
vect_z
,
tet
,
axis_x
,
axis_y
,
axis_z
)
65
-- rotate vect by tet about axis counterclockwise
66
local
c
,
s
=
cos
(
tet
*
pi
/
180
)
,
sin
(
tet
*
pi
/
180
)
67
local
r
=
1
-
c
68
local
n
=
sqrt
(
axis_x
*
axis_x
+
axis_y
*
axis_y
+
axis_z
*
axis_z
)
69
axis_x
,
axis_y
,
axis_z
=
axis_x
/
n
,
axis_y
/
n
,
axis_z
/
n
70
return
71
(
axis_x
*
axis_x
*
r
+
c
)
*
vect_x
+
(
axis_x
*
axis_y
*
r
-
axis_z
*
s
)
*
vect_y
+
(
axis_x
*
axis_z
*
r
+
axis_y
*
s
)
*
vect_z
,
72
(
axis_x
*
axis_y
*
r
+
axis_z
*
s
)
*
vect_x
+
(
axis_y
*
axis_y
*
r
+
c
)
*
vect_y
+
(
axis_y
*
axis_z
*
r
-
axis_x
*
s
)
*
vect_z
,
73
(
axis_x
*
axis_z
*
r
-
axis_y
*
s
)
*
vect_x
+
(
axis_y
*
axis_z
*
r
+
axis_x
*
s
)
*
vect_y
+
(
axis_z
*
axis_z
*
r
+
c
)
*
vect_z
74
end
75 76
local
function
make3dview
(
view
)
77 78
local
name
=
view
.
name
79
local
name
=
pdfunicode
(
name
~
=
"
"
and
name
or
"
unknown view
"
)
80 81
local
viewdict
=
pdfdictionary
{
82
Type
=
pdfconstant
(
"
3DView
"
)
,
83
XN
=
name
,
84
IN
=
name
,
85
NR
=
true
,
86
}
87 88
local
bg
=
checkedkey
(
view
,
"
bg
"
,
"
table
"
)
89
if
bg
then
90
viewdict
.
BG
=
pdfdictionary
{
91
Type
=
pdfconstant
(
"
3DBG
"
)
,
92
C
=
pdfarray
{
limited
(
bg
[
1
]
,
1
,
1
,
1
)
,
limited
(
bg
[
2
]
,
1
,
1
,
1
)
,
limited
(
bg
[
3
]
,
1
,
1
,
1
)
}
,
93
}
94
end
95 96
local
lights
=
checkedkey
(
view
,
"
lights
"
,
"
string
"
)
97
if
lights
and
schemes
[
lights
]
then
98
viewdict
.
LS
=
pdfdictionary
{
99
Type
=
pdfconstant
(
"
3DLightingScheme
"
)
,
100
Subtype
=
pdfconstant
(
lights
)
,
101
}
102
end
103 104
-- camera position is taken from 3d model
105 106
local
u3dview
=
checkedkey
(
view
,
"
u3dview
"
,
"
string
"
)
107
if
u3dview
then
108
viewdict
.
MS
=
pdfconstant
(
"
U3D
"
)
109
viewdict
.
U3DPath
=
u3dview
110
end
111 112
-- position the camera as given
113 114
local
c2c
=
checkedkey
(
view
,
"
c2c
"
,
"
table
"
)
115
local
coo
=
checkedkey
(
view
,
"
coo
"
,
"
table
"
)
116
local
roo
=
checkedkey
(
view
,
"
roo
"
,
"
number
"
)
117
local
azimuth
=
checkedkey
(
view
,
"
azimuth
"
,
"
number
"
)
118
local
altitude
=
checkedkey
(
view
,
"
altitude
"
,
"
number
"
)
119 120
if
c2c
or
coo
or
roo
or
azimuth
or
altitude
then
121 122
local
pos
=
checkedkey
(
view
,
"
pos
"
,
"
table
"
)
123
local
dir
=
checkedkey
(
view
,
"
dir
"
,
"
table
"
)
124
local
upv
=
checkedkey
(
view
,
"
upv
"
,
"
table
"
)
125
local
roll
=
checkedkey
(
view
,
"
roll
"
,
"
table
"
)
126 127
local
coo_x
,
coo_y
,
coo_z
=
0
,
0
,
0
128
local
dir_x
,
dir_y
,
dir_z
=
0
,
0
,
0
129
local
trans_x
,
trans_y
,
trans_z
=
0
,
0
,
0
130
local
left_x
,
left_y
,
left_z
=
0
,
0
,
0
131
local
up_x
,
up_y
,
up_z
=
0
,
0
,
0
132 133
-- point camera is aimed at
134 135
if
coo
then
136
coo_x
,
coo_y
,
coo_z
=
tonumber
(
coo
[
1
]
)
or
0
,
tonumber
(
coo
[
2
]
)
or
0
,
tonumber
(
coo
[
3
]
)
or
0
137
end
138 139
-- distance from camera to target
140 141
if
roo
then
142
roo
=
abs
(
roo
)
143
end
144
if
not
roo
or
roo
=
=
0
then
145
roo
=
0
.
000000000000000001
146
end
147 148
-- set it via camera position
149 150
if
pos
then
151
dir_x
=
coo_x
-
(
tonumber
(
pos
[
1
]
)
or
0
)
152
dir_y
=
coo_y
-
(
tonumber
(
pos
[
2
]
)
or
0
)
153
dir_z
=
coo_z
-
(
tonumber
(
pos
[
3
]
)
or
0
)
154
if
not
roo
then
155
roo
=
sqrt
(
dir_x
*
dir_x
+
dir_y
*
dir_y
+
dir_z
*
dir_z
)
156
end
157
if
dir_x
=
=
0
and
dir_y
=
=
0
and
dir_z
=
=
0
then
dir_y
=
1
end
158
dir_x
,
dir_y
,
dir_z
=
normalize
(
dir_x
,
dir_y
,
dir_z
)
159
end
160 161
-- set it directly
162 163
if
dir
then
164
dir_x
,
dir_y
,
dir_z
=
tonumber
(
dir
[
1
]
or
0
)
,
tonumber
(
dir
[
2
]
or
0
)
,
tonumber
(
dir
[
3
]
or
0
)
165
if
dir_x
=
=
0
and
dir_y
=
=
0
and
dir_z
=
=
0
then
dir_y
=
1
end
166
dir_x
,
dir_y
,
dir_z
=
normalize
(
dir_x
,
dir_y
,
dir_z
)
167
end
168 169
-- set it movie15 style with vector from target to camera
170 171
if
c2c
then
172
dir_x
,
dir_y
,
dir_z
=
-
tonumber
(
c2c
[
1
]
or
0
)
,
-
tonumber
(
c2c
[
2
]
or
0
)
,
-
tonumber
(
c2c
[
3
]
or
0
)
173
if
dir_x
=
=
0
and
dir_y
=
=
0
and
dir_z
=
=
0
then
dir_y
=
1
end
174
dir_x
,
dir_y
,
dir_z
=
normalize
(
dir_x
,
dir_y
,
dir_z
)
175
end
176 177
-- set it with azimuth and altitutde
178 179
if
altitude
or
azimuth
then
180
dir_x
,
dir_y
,
dir_z
=
-1
,
0
,
0
181
if
altitude
then
dir_x
,
dir_y
,
dir_z
=
rotate
(
dir_x
,
dir_y
,
dir_z
,
-
altitude
,
0
,
1
,
0
)
end
182
if
azimuth
then
dir_x
,
dir_y
,
dir_z
=
rotate
(
dir_x
,
dir_y
,
dir_z
,
azimuth
,
0
,
0
,
1
)
end
183
end
184 185
-- set it with rotation like in MathGL
186 187
if
rot
then
188
if
dir_x
=
=
0
and
dir_y
=
=
0
and
dir_z
=
=
0
then
dir_z
=
-1
end
189
dir_x
,
dir_y
,
dir_z
=
rotate
(
dir_x
,
dir_y
,
dir_z
,
tonumber
(
rot
[
1
]
)
or
0
,
1
,
0
,
0
)
190
dir_x
,
dir_y
,
dir_z
=
rotate
(
dir_x
,
dir_y
,
dir_z
,
tonumber
(
rot
[
2
]
)
or
0
,
0
,
1
,
0
)
191
dir_x
,
dir_y
,
dir_z
=
rotate
(
dir_x
,
dir_y
,
dir_z
,
tonumber
(
rot
[
3
]
)
or
0
,
0
,
0
,
1
)
192
end
193 194
-- set it with default movie15 orientation looking up y axis
195 196
if
dir_x
=
=
0
and
dir_y
=
=
0
and
dir_z
=
=
0
then
dir_y
=
1
end
197 198
-- left-vector
199
-- up-vector
200 201
if
upv
then
202
up_x
,
up_y
,
up_z
=
tonumber
(
upv
[
1
]
)
or
0
,
tonumber
(
upv
[
2
]
)
or
0
,
tonumber
(
upv
[
3
]
)
or
0
203
else
204
-- set default up-vector
205
if
abs
(
dir_x
)
=
=
0
and
abs
(
dir_y
)
=
=
0
then
206
if
dir_z
<
0
then
207
up_y
=
1
-- top view
208
else
209
up_y
=
-1
-- bottom view
210
end
211
else
212
-- other camera positions than top and bottom, up-vector = up_world - (up_world dot dir) dir
213
up_x
,
up_y
,
up_z
=
-
dir_z
*
dir_x
,
-
dir_z
*
dir_y
,
-
dir_z
*
dir_z
+
1
214
end
215
end
216 217
-- normalize up-vector
218 219
up_x
,
up_y
,
up_z
=
normalize
(
up_x
,
up_y
,
up_z
)
220 221
-- left vector = up x dir
222 223
left_x
,
left_y
,
left_z
=
dir_z
*
up_y
-
dir_y
*
up_z
,
dir_x
*
up_z
-
dir_z
*
up_x
,
dir_y
*
up_x
-
dir_x
*
up_y
224 225
-- normalize left vector
226 227
left_x
,
left_y
,
left_z
=
normalize
(
left_x
,
left_y
,
left_z
)
228 229
-- apply camera roll
230 231
if
roll
then
232
local
sinroll
=
sin
(
(
roll
/
180
.
0
)
*
pi
)
233
local
cosroll
=
cos
(
(
roll
/
180
.
0
)
*
pi
)
234
left_x
=
left_x
*
cosroll
+
up_x
*
sinroll
235
left_y
=
left_y
*
cosroll
+
up_y
*
sinroll
236
left_z
=
left_z
*
cosroll
+
up_z
*
sinroll
237
up_x
=
up_x
*
cosroll
+
left_x
*
sinroll
238
up_y
=
up_y
*
cosroll
+
left_y
*
sinroll
239
up_z
=
up_z
*
cosroll
+
left_z
*
sinroll
240
end
241 242
-- translation vector
243 244
trans_x
,
trans_y
,
trans_z
=
coo_x
-
roo
*
dir_x
,
coo_y
-
roo
*
dir_y
,
coo_z
-
roo
*
dir_z
245 246
viewdict
.
MS
=
pdfconstant
(
"
M
"
)
247
viewdict
.
CO
=
roo
248
viewdict
.
C2W
=
pdfarray
{
249
left_x
,
left_y
,
left_z
,
250
up_x
,
up_y
,
up_z
,
251
dir_x
,
dir_y
,
dir_z
,
252
trans_x
,
trans_y
,
trans_z
,
253
}
254 255
end
256 257
local
aac
=
tonumber
(
view
.
aac
)
-- perspective projection
258
local
mag
=
tonumber
(
view
.
mag
)
-- ortho projection
259 260
if
aac
and
aac
>
0
and
aac
<
180
then
261
viewdict
.
P
=
pdfdictionary
{
262
Subtype
=
pdfconstant
(
"
P
"
)
,
263
PS
=
pdfconstant
(
"
Min
"
)
,
264
FOV
=
aac
,
265
}
266
elseif
mag
and
mag
>
0
then
267
viewdict
.
P
=
pdfdictionary
{
268
Subtype
=
pdfconstant
(
"
O
"
)
,
269
OS
=
mag
,
270
}
271
end
272 273
local
mode
=
modes
[
view
.
rendermode
]
274
if
mode
then
275
pdfdictionary
{
276
Type
=
pdfconstant
(
"
3DRenderMode
"
)
,
277
Subtype
=
pdfconstant
(
mode
)
,
278
}
279
end
280 281
-- crosssection
282 283
local
crosssection
=
checkedkey
(
view
,
"
crosssection
"
,
"
table
"
)
284
if
crosssection
then
285
local
crossdict
=
pdfdictionary
{
286
Type
=
pdfconstant
(
"
3DCrossSection
"
)
287
}
288 289
local
c
=
checkedkey
(
crosssection
,
"
point
"
,
"
table
"
)
or
checkedkey
(
crosssection
,
"
center
"
,
"
table
"
)
290
if
c
then
291
crossdict
.
C
=
pdfarray
{
tonumber
(
c
[
1
]
)
or
0
,
tonumber
(
c
[
2
]
)
or
0
,
tonumber
(
c
[
3
]
)
or
0
}
292
end
293 294
local
normal
=
checkedkey
(
crosssection
,
"
normal
"
,
"
table
"
)
295
if
normal
then
296
local
x
,
y
,
z
=
tonumber
(
normal
[
1
]
or
0
)
,
tonumber
(
normal
[
2
]
or
0
)
,
tonumber
(
normal
[
3
]
or
0
)
297
if
sqrt
(
x
*
x
+
y
*
y
+
z
*
z
)
=
=
0
then
298
x
,
y
,
z
=
1
,
0
,
0
299
end
300
crossdict
.
O
=
pdfarray
{
301
pdfnull
,
302
atan2
(
-
z
,
sqrt
(
x
*
x
+
y
*
y
)
)
*
180
/
pi
,
303
atan2
(
y
,
x
)
*
180
/
pi
,
304
}
305
end
306 307
local
orient
=
checkedkey
(
crosssection
,
"
orient
"
,
"
table
"
)
308
if
orient
then
309
crossdict
.
O
=
pdfarray
{
310
tonumber
(
orient
[
1
]
)
or
1
,
311
tonumber
(
orient
[
2
]
)
or
0
,
312
tonumber
(
orient
[
3
]
)
or
0
,
313
}
314
end
315 316
crossdict
.
IV
=
cross
.
intersection
or
false
317
crossdict
.
ST
=
cross
.
transparent
or
false
318 319
viewdict
.
SA
=
next
(
crossdict
)
and
pdfarray
{
crossdict
}
-- maybe test if # > 1
320
end
321 322
local
nodes
=
checkedkey
(
view
,
"
nodes
"
,
"
table
"
)
323
if
nodes
then
324
local
nodelist
=
pdfarray
(
)
325
for
i
=
1
,
#
nodes
do
326
local
node
=
checkedkey
(
nodes
,
i
,
"
table
"
)
327
if
node
then
328
local
position
=
checkedkey
(
node
,
"
position
"
,
"
table
"
)
329
nodelist
[
#
nodelist
+
1
]
=
pdfdictionary
{
330
Type
=
pdfconstant
(
"
3DNode
"
)
,
331
N
=
node
.
name
or
(
"
node_
"
.
.
i
)
,
-- pdfunicode ?
332
M
=
position
and
#
position
=
=
12
and
pdfarray
(
position
)
,
333
V
=
node
.
visible
or
true
,
334
O
=
node
.
opacity
or
0
,
335
RM
=
pdfdictionary
{
336
Type
=
pdfconstant
(
"
3DRenderMode
"
)
,
337
Subtype
=
pdfconstant
(
node
.
rendermode
or
"
Solid
"
)
,
338
}
,
339
}
340
end
341
end
342
viewdict
.
NA
=
nodelist
343
end
344 345
return
viewdict
346 347
end
348 349
local
stored_js
,
stored_3d
,
stored_pr
,
streams
=
{
}
,
{
}
,
{
}
,
{
}
350 351
local
f_image
=
formatters
[
"
q /GS gs %.6N 0 0 %.6N 0 0 cm /IM Do Q
"
]
352 353
local
function
insert3d
(
spec
)
-- width, height, factor, display, controls, label, foundname
354 355
local
width
,
height
,
factor
=
spec
.
width
,
spec
.
height
,
spec
.
factor
or
number
.
dimenfactors
.
bp
356
local
display
,
controls
,
label
,
foundname
=
spec
.
display
,
spec
.
controls
,
spec
.
label
,
spec
.
foundname
357 358
local
param
=
(
display
and
parametersets
[
display
]
)
or
{
}
359
local
streamparam
=
(
controls
and
parametersets
[
controls
]
)
or
{
}
360
local
name
=
"
3D Artwork
"
.
.
(
param
.
name
or
label
or
"
Unknown
"
)
361 362
local
activationdict
=
pdfdictionary
{
363
TB
=
pdfboolean
(
param
.
toolbar
,
true
)
,
364
NP
=
pdfboolean
(
param
.
tree
,
false
)
,
365
}
366 367
local
stream
=
streams
[
label
]
368
if
not
stream
then
369 370
local
subtype
,
subdata
=
"
U3D
"
,
io
.
loaddata
(
foundname
)
or
"
"
371
if
find
(
subdata
,
"
^PRC
"
)
then
372
subtype
=
"
PRC
"
373
elseif
find
(
subdata
,
"
^U3D
"
)
then
374
subtype
=
"
U3D
"
375
elseif
file
.
suffix
(
foundname
)
=
=
"
prc
"
then
376
subtype
=
"
PRC
"
377
end
378 379
local
attr
=
pdfdictionary
{
380
Type
=
pdfconstant
(
"
3D
"
)
,
381
Subtype
=
pdfconstant
(
subtype
)
,
382
}
383
local
streamviews
=
checkedkey
(
streamparam
,
"
views
"
,
"
table
"
)
384
if
streamviews
then
385
local
list
=
pdfarray
(
)
386
for
i
=
1
,
#
streamviews
do
387
local
v
=
checkedkey
(
streamviews
,
i
,
"
table
"
)
388
if
v
then
389
list
[
#
list
+
1
]
=
make3dview
(
v
)
390
end
391
end
392
attr
.
VA
=
list
393
end
394
if
checkedkey
(
streamparam
,
"
view
"
,
"
table
"
)
then
395
attr
.
DV
=
make3dview
(
streamparam
.
view
)
396
elseif
checkedkey
(
streamparam
,
"
view
"
,
"
string
"
)
then
397
attr
.
DV
=
streamparam
.
view
398
end
399
local
js
=
checkedkey
(
streamparam
,
"
js
"
,
"
string
"
)
400
if
js
then
401
local
jsref
=
stored_js
[
js
]
402
if
not
jsref
then
403
jsref
=
pdfflushstreamfileobject
(
js
)
404
stored_js
[
js
]
=
jsref
405
end
406
attr
.
OnInstantiate
=
pdfreference
(
jsref
)
407
end
408
stored_3d
[
label
]
=
pdfflushstreamfileobject
(
foundname
,
attr
)
409
stream
=
1
410
else
411
stream
=
stream
+
1
412
end
413
streams
[
label
]
=
stream
414 415
local
name
=
pdfunicode
(
name
)
416 417
local
annot
=
pdfdictionary
{
418
Subtype
=
pdfconstant
(
"
3D
"
)
,
419
T
=
name
,
420
Contents
=
name
,
421
NM
=
name
,
422
[
"
3DD
"
]
=
pdfreference
(
stored_3d
[
label
]
)
,
423
[
"
3DA
"
]
=
activationdict
,
424
}
425
if
checkedkey
(
param
,
"
view
"
,
"
table
"
)
then
426
annot
[
"
3DV
"
]
=
make3dview
(
param
.
view
)
427
elseif
checkedkey
(
param
,
"
view
"
,
"
string
"
)
then
428
annot
[
"
3DV
"
]
=
param
.
view
429
end
430 431
local
preview
=
checkedkey
(
param
,
"
preview
"
,
"
string
"
)
432
if
preview
then
433
activationdict
.
A
=
pdfconstant
(
"
XA
"
)
434
local
tag
=
formatters
[
"
%s:%s:%s
"
]
(
label
,
stream
,
preview
)
435
local
ref
=
stored_pr
[
tag
]
436
if
not
ref
then
437
local
figure
=
embedimage
{
438
filename
=
preview
,
439
width
=
width
,
440
height
=
height
441
}
442
ref
=
figure
.
objnum
443
stored_pr
[
tag
]
=
ref
444
end
445
if
ref
then
-- see back-pdf ** .. here we have a local /IM !
446
local
pw
=
pdfdictionary
{
447
Type
=
pdfconstant
(
"
XObject
"
)
,
448
Subtype
=
pdfconstant
(
"
Form
"
)
,
449
FormType
=
1
,
450
BBox
=
pdfarray
{
0
,
0
,
pdfnumber
(
factor
*
width
)
,
pdfnumber
(
factor
*
height
)
}
,
451
Matrix
=
pdfarray
{
1
,
0
,
0
,
1
,
0
,
0
}
,
452
ProcSet
=
lpdf
.
procset
(
)
,
453
Resources
=
pdfdictionary
{
454
XObject
=
pdfdictionary
{
455
IM
=
pdfreference
(
ref
)
456
}
457
}
,
458
ExtGState
=
pdfdictionary
{
459
GS
=
pdfdictionary
{
460
Type
=
pdfconstant
(
"
ExtGState
"
)
,
461
CA
=
1
,
462
ca
=
1
,
463
}
464
}
,
465
}
466
local
pwd
=
pdfflushstreamobject
(
f_image
(
factor
*
width
,
factor
*
height
)
,
pw
)
467
annot
.
AP
=
pdfdictionary
{
468
N
=
pdfreference
(
pwd
)
469
}
470
end
471
return
annot
,
figure
,
ref
472
else
473
activationdict
.
A
=
pdfconstant
(
"
PV
"
)
474
return
annot
,
nil
,
nil
475
end
476
end
477 478
function
nodeinjections
.
insertu3d
(
spec
)
479
local
annotation
,
preview
,
ref
=
insert3d
{
-- just spec
480
foundname
=
spec
.
foundname
,
481
width
=
spec
.
width
,
482
height
=
spec
.
height
,
483
factor
=
spec
.
factor
,
484
display
=
spec
.
display
,
485
controls
=
spec
.
controls
,
486
label
=
spec
.
label
,
487
}
488
node
.
write
(
nodeinjections
.
annotation
(
spec
.
width
,
spec
.
height
,
0
,
annotation
(
)
)
)
489
end
490