5
$\begingroup$

I tried to create Graphics primitives using the techniques in this, found problems with parallel rasterization

SetAttributes[createPrimitive,HoldAll];

createPrimitive[patt_,expr_]:=Typeset`MakeBoxes[p:patt,fmt_,Graphics]:=Typeset`MakeBoxes[Interpretation[expr,p],fmt,Graphics];

createPrimitive[face[x_:0.1],{Circle[{0,0},1],Circle[{-0.3,0.5},x],Circle[{0.3,0.5},x],Line[{{-0.4,-0.2},{0.4,-0.2}}]}];

ParallelTable[Graphics[{face[i]},ImageSize->Tiny],{i,0,0.3,0.3/5}]
ParallelTable[Rasterize@Graphics[{face[i]},ImageSize->Tiny],{i,0,0.3,0.3/5}]

enter image description here

Is there any way to fix this?

$\endgroup$
5
  • $\begingroup$ Your problem is that "face" is not defined. $\endgroup$ Commented Apr 26, 2023 at 7:34
  • $\begingroup$ @DanielHuber No, things defined with Typeset`MakeBoxes, the FrontEnd doesn't color. $\endgroup$
    – expression
    Commented Apr 26, 2023 at 9:29
  • $\begingroup$ Type ?? face and you will see that face is not defined. Or look at the color. $\endgroup$ Commented Apr 26, 2023 at 13:25
  • $\begingroup$ @DanielHuber As mentioned by OP, in this case we've just added a down value for Typeset`MakeBoxes, try #[[Position[#, face[__], Infinity] // Flatten // First]] &[ DownValues@Typeset`MakeBoxes]. For more info, please read the linked post in the question carefully. $\endgroup$
    – xzczd
    Commented Apr 26, 2023 at 13:49
  • $\begingroup$ @xzczd Tnank you for the hint, I did not know this method. $\endgroup$ Commented Apr 26, 2023 at 16:04

1 Answer 1

5
$\begingroup$

I think this is probably related to Parallel evaluation of Image and Rasterize problem. Briefly, Rasterize is not done by the kernel but by the front-end.

For example, when you don't include rasterization, the output of ParallelTable is still Graphics[{face[...]}], and it is then the main front-end that afterwards converts this to your shapes.

ParallelTable[InputForm@Graphics[{face[i]}, ImageSize -> Tiny], {i, {0, .2}}]
(* {Graphics[{face[0]}, ImageSize -> Tiny],
    Graphics[{face[0.2]}, ImageSize -> Tiny]} *)

ParallelTable[ToBoxes@Graphics[{face[i]}, ImageSize -> Tiny], {i, {0, .2}}]
(* {GraphicsBox[{face[0]}, ImageSize -> Tiny], 
    GraphicsBox[{face[0.2]}, ImageSize -> Tiny]}

Therefore, you need to somehow get your definitions to the front-ends that are initiated by the subkernels. DistributeDefinitions doesn't work, but ParallelEvaluate seems to do the job. Maybe there are also some other viable solutions.

ParallelEvaluate[
 SetAttributes[createPrimitive, HoldAll];
 createPrimitive[patt_, expr_] := 
  Typeset`MakeBoxes[p : patt, fmt_, Graphics] := 
   Typeset`MakeBoxes[Interpretation[expr, p], fmt, Graphics];
 createPrimitive[
  face[x_ : 0.1], {Circle[{0, 0}, 1], Circle[{-0.3, 0.5}, x], 
   Circle[{0.3, 0.5}, x], Line[{{-0.4, -0.2}, {0.4, -0.2}}]}];];

ParallelTable[Rasterize@Graphics[{face[i]}, ImageSize -> Tiny], {i, 0, 0.3, 0.3/5}]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ This is surprising. BTW it's worth mentioning that DistributedContexts->All doesn't work, either. (+1, of course. ) $\endgroup$
    – xzczd
    Commented Apr 26, 2023 at 12:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.