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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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