klayout
klayout copied to clipboard
Bezier curves
Dear @klayoutmatthias,
Would it be possible to add bezier curves for polygons in the "Basic" library?
For photonics, we use them for drawing waveguides.
https://support.lumerical.com/hc/en-us/articles/360034382234-Waveguide-Simulation-Object
We have also implemented this in SiEPIC-Tools https://github.com/SiEPIC/SiEPIC-Tools, but it would be nice if it was natively supported in KLayout.
thank you Lukas
I have two questions: Q1: How do you envision using it in practice? For a Bezier you need four points. Do you suggest the user provides the four points as a path perhaps? Q2: Why would this be useful in the Basic Library if the SiEPIC library can provide the same functionality?
For reference, I found the implementation of the ROUND_PATH PCell from the basic library: It's only 150 lines. https://github.com/KLayout/klayout/blob/master/src/lib/lib/libBasicRoundPath.cc
The Bezier cell would be something similar. But I wonder what is the advantage of it being native if klayout needs extension anyways for photonics.
@thomaslima – good questions.
-
ROUND_PATH: I originally used that for the waveguide functionality. It is super fast and efficient. We stopped using ROUND_PATH because it did not support bezier curves.
-
Hence we developed waveguides in SiEPIC-Tools written as Python functions with a bezier implementation.
-
The Waveguide PCell also does other things like adding pins, compact model information, loading technology information about which layers and widths are required, etc. The drawing is a separate function, and performance would improve if it was a built-in functionality in KLayout
-
Bezier curves are common in many fields, and there are many libraries that do it. Having a standard for this included in KLayout would help everyone to just use one thing. If we agree on control point definitions, that would make it easier for interoperability as well.
-
for a cubic bezier waveguide you need 4 points (8 numbers). What I imagine is that the SiEPIC-Tools Waveguide PCells would convert the user parameters [P0 and P3: start & end points; Waveguide Type] and the parameters from the technology specific for the waveguide type (Waveguides.XML) [radius, bezier parameter, gds layers, widths, offsets] into the required P0-P3 control points.
-
BASIC Library "Bezier path" – being a Path-like object with fixed width but stored as a Polygon – could then have inputs:
- P0, P1, P2, P3, width
-
BASIC Library "Bezier polygon" – being a Polygon object where there are two sides which might have different bezier curves - could then have inputs:
- P0a, P0b, P1b, P1b, P2a, P2b, P3a, P3b
In summary, the request here is to have a super efficient quality-controlled implementation that is universally accepted and used, not only by SiEPIC, but other users, including in other fields (MEMS).
regards Lukas
Okay. I suppose I would summarize your answer as "higher speed" and "creating a standard".
The cubic Bezier formula is uniquely defined by a function B(t), with 0<=t<=1 (lumerical and wikipedia agree), but one thing that is not trivial is where to sample along the bezier function. In zeropdk, I use a dynamic optimization that calculates where to sample the curve based on some tolerance. ROUND_PATH asks you to specify the number of points per circle, then samples uniformly at each arc. This optimization is computationally expensive and it doesn't sound like a good approach for this.
Another option is to uniformly sample in t [0,1], but that risks introducing bad artifacts in edge cases. A mid-way approach is to use guess-and-resample iterations, like in this article. I would recommend this approach.
Regarding the Bezier polygon, I wonder what are the use cases. If the idea is to draw an offset curve to the original bezier path, it won't work, since the offset curve is not a bezier curve, and it is actually quite expensive to compute analytically, but should be doable numerically, and it will introduce potentially self-intersecting polygons in edge cases.
I don't know if it is feasible to do the Polygon case and have it be based on an underlying Polygon because the way klayout orders the points for polygons is not preserved, I think.
I could take a stab at converting zeropdk's method to klayout c++, the remaining question being whether @klayoutmatthias would accept this addition to the library, since he'll have to maintain.
My recommendation, which would address your motivation, is to include a c++ algorithm that computes a bezier path, that you can call from ruby or python and use this function to create the waveguide PCell in third-party libraries. If everyone uses the same method, then it should be fast and it should be standard.
-
for the Bezier Polygon: a) use case is a bend where the width varies along the path; having an inner and outer path would provide design freedom. I haven't done this myself, but have seen it, and believe it would be an excellent way to create a 90º bend between wide multimode waveguides. b) Polygon class: I imagine that the polygon would be stored in GDS, but the PCell parameters and cell name would also be stored there so they can be recomputed. Hence I don't see the ordering of points being an issue, as the PCell parameters will still be available if needed.
-
the algorithm you found for sampling the bezier curve looks excellent.
-
perhaps improving and standardizing the zeropdk implementation, and making sure it is used in SiEPIC-Tools, could be a first step. Once that's done, and everyone agrees, then convert to C++?
- As you probably know, my solution for the first has been to use a function to layout a waveguide with varying widths. This function accepts either a single width, or a pair of widths (initial and final), which gets interpolated along the way according to arc-length, or a list of widths with the same length as the point list. I use this mostly for metal traces since I don't work with multimode waveguides and would never dare to do a multimode turn. :)
- The issue is that although the above function might work within all versions of python, zeropdk itself not safe for all python versions (I require it to be >=3.6 in the setup, for example). I do welcome contributions from your group to expand the python versions and to have it integrated with SiEPIC. Once zeropdk becomes a dependency of siepic, then I believe there are a lot more opportunities for things like advanced waveguides, or basic channel routing, or pcell instantiation.
Note: this is related to #193. In that discussion, I would favor the svg-path (composite Bezier) method, because as a designer I like to ensure the curve passes through some designated points, and I like to control the tangent vector at those points. It is also a simple extension, requiring just a list of points, not requiring weights as well.
It would be cool if klayout could support composite beziers. For a nice visual representation, we would need, I think, an extension of the path object that displays control points as well as knots.
and the parameters from the technology specific for the waveguide type (Waveguides.XML) [radius, bezier parameter, gds layers, widths, offsets] into the required P0-P3 control points.
To be clear here -- the technology / DRC rules set restrictions on what radius / width / offset of curve is manufacturable, correct?
@riking
I am less worried about manufacturing, but rather the performance of the device.
Specifically, I would like to make a 90º bend with the minimum amount of space and loss. Here is how I use it for strip waveguides at 1550 nm, with 220 nm thickness, and 500 nm width.