Cheating a bit:
a = {{-1, 0}, {0, 1}, {1, 0}}; b = {{0, -2/3}};
big = First @ Cases[ParametricPlot[BezierFunction[2 a][t], {t, 0, 1}], Line[l_] :> l, ∞];
small = First @ Cases[ParametricPlot[BezierFunction[a][t], {t, 0, 1}], Line[l_] :> l, ∞];
Graphics3D[{Directive[Black, EdgeForm[]], Polygon[Map[Append[#, 0] &,
(2 b) ~Join~ big ~Join~ (2 b) ~Join~ b ~Join~ Reverse[small] ~Join~ b]]},
Lighting -> "Neutral"]
I decided to extend Simon's fine answer to be able to handle both Béziers and B-splines, as well as enabling adaptive sampling. Here is the result:
toSegments[fc_FilledCurve] :=
First @ If[Length[fc] == 1, Identity, GeometricFunctions`DecodeFilledCurve][fc]
sampleSegment[prims_List, opts___] :=
If[First[#] != Last[#], Append[#, First[#]], #] &[
Apply[Join, prims /. {(b : (BSplineCurve | BezierCurve))[data_, rest___] :>
Block[{bf, h, t},
h = Switch[b, BSplineCurve, BSplineFunction, BezierCurve, BezierFunction];
bf = Apply[h, {data, rest} /.
(SplineDegree -> 3) :> (SplineDegree -> Automatic)];
First @ Cases[ParametricPlot[bf[t], {t, 0, 1}, opts], Line[l_] :> l, ∞]],
Line -> Sequence}]]
filledCurvetoPolygon[fc_FilledCurve] := With[{s = sampleSegment /@ toSegments[fc]},
Polygon[ArrayPad[Join @@ (Append[#, s[[1, -1]]] & /@ s), {{0, 0}, {0, 1}}]]]
Examples:
Graphics3D[filledCurvetoPolygon[First @ Cases[
ImportString[ExportString["AB", "PDF"]], _FilledCurve, ∞]]]
pts = {{0., -0.5}, {0.5, -0.5}, {0.5, 0.5}, {0., 0.5}, {-0.5, 0.5},
{-0.5, -0.5}, {0., -0.5}};
w = {1, .5, .5, 1, .5, .5, 1};
k = {0, 0, 0, 1/4, 1/2, 1/2, 3/4, 1, 1, 1};
FilledCurve[{{BSplineCurve[2 pts, SplineDegree -> 2, SplineKnots -> k, SplineWeights -> w]},
{BSplineCurve[pts, SplineDegree -> 2, SplineKnots -> k, SplineWeights -> w]}}]
// filledCurvetoPolygon // Graphics3D
FilledCurve
s would be very useful indeed... $\endgroup$DiscretizeGraphics
. $\endgroup$