How to make "empty" point in Asymptote?

I drew several pictures in tiz-euclide and I made the dots look like this: Now I have switched to 3D diagrams. I am making them in Asymptote as this was the best suggestion from this forum and it can make intersections of 3D paths. The question is how to make the points in 3D look the same for the document to be uniform.

The points in 2D were defined using a style:

\tikzset{point/.style={circle, thick, %
draw=black,fill=white, inner sep=0pt,minimum size=3pt}}

Bare 'dot' in Asymptote produces this:

\documentclass{article}
\usepackage{asymptote}
\begin{document}
\begin{asy}
settings.outformat = "pdf";
settings.render = 0;
import three;
size(10cm, 0);
currentprojection=orthographic((5,2,2));
pen dot_style=makepen(scale(3pt)*unitcircle);
real a=3;
real b=4;
real c=4;
triple A=(0,0,a);
triple B=(0,b,0);
triple C=(c,0,0);
draw(A--B--C--A,linewidth(1));
draw(O--A^^O--B^^O--C,dashed);
path3 p=O--(6,6*c/b,0);
path3 q=B--C;
path3 p1=O--(6,0,6*c/a);
path3 q1=A--C;
triple H1=intersectionpoint(p,q);
triple H2=intersectionpoint(p1,q1);
path3 h1=A--H1;
path3 h2=B--H2;
triple H=intersectionpoint(h1,h2);
draw(h1);
draw(h2);
draw(O--H);
dot(Label("$H_1$",align=W),H2,dot_style);
dot(Label("$H_2$",align=S),H1,dot_style);
dot(Label("$H$",align=NE),H,dot_style);
dot(Label("$A$",align=N),A,dot_style);
dot(Label("$B$",align=E),B,dot_style);
dot(Label("$C$",align=W),C,dot_style);
dot(Label("$O$",align=S),O,dot_style);
\end{asy}
\end{document}

Output: I found it ugly and want to make those empty points of the same size. I feel it is easy. Any ideas how to modify

pen dot_style=makepen(scale(3pt)*unitcircle);

? Thank you.

Short answer: In Asymptote 2D, this functionality is available as in the following example:

dot((2/3, 2/3), filltype=FillDraw(fillpen=white, drawpen=black));

Unfortunately that can't be carried over to 3d.

Long answer: It can be done, at least if settings.render=0 (which it is in your case), but you've basically got to rebuild the dot functionality from three_surface.asy. Here's my attempt:

settings.outformat = "pdf";
settings.prc = false;  // IMPORTANT
settings.render = 0;   // IMPORTANT
import three;
size(10cm, 0);
currentprojection=orthographic((5,2,2));

void opendot(picture pic=currentpicture, triple v, material p=currentpen,
light light=nolight, string name="", render render=defaultrender)
{
pen q=(pen) p;
pen fillpen = light.background;
if (invisible(fillpen)) fillpen = currentlight.background;
if (invisible(fillpen)) fillpen = white;
real size=0.5*linewidth(dotsize(q)+q);
pic.add(new void(frame f, transform3 t, picture pic, projection P) {
triple V=t*v;
assert(!is3D(), "opendot() not supported unless settings.prc == false and settings.render != 0");
if(pic != null)
dot(pic,project(V,P.t),filltype=FillDraw(fillpen=fillpen, drawpen=q));
},true);
triple R=size*(1,1,1);
}

void opendot(picture pic=currentpicture, Label L, triple v, align align=NoAlign,
string format=defaultformat, material p=currentpen,
light light=nolight, string name="", render render=defaultrender)
{
Label L=L.copy();
if(L.s == "") {
if(format == "") format=defaultformat;
L.s="("+format(format,v.x)+","+format(format,v.y)+","+
format(format,v.z)+")";
}
L.align(align,E);
L.p((pen) p);
opendot(pic,v,p,light,name,render);
label(pic,L,v,render);
}

dotfactor *= 2;  // Make dots twice as big as they are by default.
real a=3;
real b=4;
real c=4;
triple A=(0,0,a);
triple B=(0,b,0);
triple C=(c,0,0);
draw(A--B--C--A,linewidth(1));
draw(O--A^^O--B^^O--C,dashed);
path3 p=O--(6,6*c/b,0);
path3 q=B--C;
path3 p1=O--(6,0,6*c/a);
path3 q1=A--C;
triple H1=intersectionpoint(p,q);
triple H2=intersectionpoint(p1,q1);
path3 h1=A--H1;
path3 h2=B--H2;
triple H=intersectionpoint(h1,h2);
draw(h1);
draw(h2);
draw(O--H);
opendot(Label("$H_1$",align=W),H2);
opendot(Label("$H_2$",align=S),H1);
opendot(Label("$H$",align=NE),H);
opendot(Label("$A$",align=N),A);
opendot(Label("$B$",align=E),B);
opendot(Label("$C$",align=W),C);
opendot(Label("$O$",align=S),O);
• Thank you, Charles. This works! Frankly speaking, I don't completely understand why (many commands are not familiar to me) - I will study the manual and figure it out. Thanks again for inspiring 'to think' in Asymptote in programming terms (i mean to introduce all these user-defined functions and so on) Jul 31 '16 at 23:20
• The manual won't be all that helpful here. I basically just modified two of the dot commands from three_surface.asy. The code involves the double-deferred drawing process, and I don't fully understand it myself. Aug 1 '16 at 2:22