Comments (1)
I spent some time today combing through path.py
and marked what I have found to be the lines causing the issue:
@cell
def extrude(
p: Path,
cross_section: CrossSectionSpec | None = None,
layer: LayerSpec | None = None,
width: float | None = None,
simplify: float | None = None,
shear_angle_start: float | None = None,
shear_angle_end: float | None = None,
allow_offgrid: bool | None = None,
snap_to_grid: bool = False,
add_bbox: bool = True,
) -> Component:
# Skipping lines
if section.insets and section.insets != (0, 0):
p_pts = p_sec.points
new_x_start = p.xmin + section.insets[0]
new_x_stop = p.xmax - section.insets[1]
if new_x_start > np.max(p_pts[:, 0]) or new_x_stop < np.min(p_pts[:, 0]):
warnings.warn(
f"Cannot apply delay to Section '{section.name}', delay results in points outside of original path.",
stacklevel=3,
)
continue
new_start_idx = np.argwhere(p_pts[:, 0] > new_x_start)[0, 0] # <---
new_stop_idx = np.argwhere(p_pts[:, 0] < new_x_stop)[-1, 0] # <---
new_start_point = [new_x_start, p_pts[new_start_idx, 1]]
new_stop_point = [new_x_stop, p_pts[new_stop_idx, 1]]
p_sec = Path(
[new_start_point, *p_pts[new_start_idx:new_stop_idx], new_stop_point] # <---
)
# Skipping Lines
From what I understand, the problem I ran into is being caused by the fact that the path ends in a non-horizontal straight.
So, when it finds new_stop_idx
,
new_stop_idx = np.argwhere(p_pts[:, 0] < new_x_stop)[-1, 0]
the index of the first x-position that is less than new_x_stop
is all the way back at the end of the bend, so gf.path.extrude()
then tries to draw the last point at the same y-position as the second to last point.
An additional (potential) problem I noticed is that the insets are applied solely along the x-axis. This means that even if the specific issue of the new inset points being drawn horizontally is fixed, the inset amount may still be more than expected if the start or end of the path is angled. I am relatively new to layout and GDSFactory, so I don't know if the convention for inset amounts is normally to apply it across a single axis, but if it isn't, I believe having the inset amount relative to the overall path length would be more intuitive for the user.
My proposed methodology is to:
-
Find the difference array of the path (each (x, y) pair can then be treated as a vector describing each segment of the path)
-
Calculate the norm of each vector in the difference array to find each segment length
-
Find where the inset value is less than or equal to the cumulative sum of the normed difference array or reversed normed difference array in the case of the end inset (similar to existing method except index would now be relative to the path length)
-
Get the vectors that correspond to the path segments the insets overlap with along the path
-
Find the unit vectors of the vectors found in step 4
-
Calculate the difference between the start/stop inset values and the path length up to the indices found in step 3 and multiply by the respective unit vectors found in step 5
-
Translate vectors back to their proper position along the original path
-
Construct the new path array
I believe this should enable arbitrary path extrusion on any otherwise valid gf.cross-section.Section
I know that writing this out is likely not the easiest way to interpret what I mean - I just put in a PR with my suggested changes. Any suggested edits are more than welcome!
from gdsfactory.
Related Issues (20)
- Port.layer returns an integer HOT 4
- Question: Roughness in euler_bend_all_angle HOT 6
- Improper cache hits for some components in v7 HOT 1
- type object 'LAYER' has not attribute 'kcl' HOT 1
- RuntimeError: Cannot write layer numbers larger than 65535 to GDS2 streams HOT 2
- remap_layers does not remap layers HOT 3
- The get_ports_list() function does not work in the reference device. HOT 1
- The port doesn't seem to work HOT 2
- `route_from_single_steps` is missing a straight `ComponentSpec` argument
- get_cells looks at cell decorated functions instead of type annotations
- import gds error: borrowing component from another PDK HOT 4
- Pass list of the components or references to boolean function HOT 1
- Importing gdsfactory changes `yaml.safe_load` behavior HOT 1
- Klayout integration stopped working HOT 1
- ValueError: ref() is deprecated. Use add_ref() instead HOT 1
- Resolve Port Positions Recursively from a Top Component in V8 HOT 5
- Colab examples on docs site no longer run after gf requiring python 3.11 HOT 3
- Consistency of the commands. HOT 2
- .dmove() (and .move()) not compatible with Port or DPoint arguments
- How to Obtain the Rotation of a ComponentReference in V8 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gdsfactory.