{"action":"created","issue":{"url":"https://api.github.com/repos/heitzmann/gdspy/issues/3","labels_url":"https://api.github.com/repos/heitzmann/gdspy/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/heitzmann/gdspy/issues/3/comments","events_url":"https://api.github.com/repos/heitzmann/gdspy/issues/3/events","html_url":"https://github.com/heitzmann/gdspy/issues/3","id":129895506,"number":3,"title":"Offset method robustness for complex shapes","user":{"login":"okianus","id":12171143,"avatar_url":"https://avatars.githubusercontent.com/u/12171143?v=3","gravatar_id":"","url":"https://api.github.com/users/okianus","html_url":"https://github.com/okianus","followers_url":"https://api.github.com/users/okianus/followers","following_url":"https://api.github.com/users/okianus/following{/other_user}","gists_url":"https://api.github.com/users/okianus/gists{/gist_id}","starred_url":"https://api.github.com/users/okianus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/okianus/subscriptions","organizations_url":"https://api.github.com/users/okianus/orgs","repos_url":"https://api.github.com/users/okianus/repos","events_url":"https://api.github.com/users/okianus/events{/privacy}","received_events_url":"https://api.github.com/users/okianus/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-01-29T22:06:01Z","updated_at":"2016-01-29T22:43:03Z","closed_at":null,"body":"The offset method for shapes that \"close\" upon themselves (i.e. enlarged such that the resulting polygon structure has overlapping portions) results in  segmentation fault (SIGSEGV). \r\n\r\nAs a simple example -- letter C, drawn as a single polygon, and then enlarged using the offset method:\r\n\r\n```\r\nimport gdspy\r\nimport numpy\r\n\r\ncell = gdspy.Cell('CELL')\r\nc_coords = numpy.array([  [ 0.6663    ,  0.32629112],\r\n                          [ 0.6663    ,  0.1669    ],\r\n                          [ 0.4994    ,  0.        ],\r\n                          [ 0.1669    ,  0.        ],\r\n                          [ 0.        ,  0.1669    ],\r\n                          [ 0.        ,  0.8331    ],\r\n                          [ 0.1669    ,  1.        ],\r\n                          [ 0.4994    ,  1.        ],\r\n                          [ 0.6663    ,  0.8331    ],\r\n                          [ 0.6663    ,  0.67370888],\r\n                          [ 0.4994    ,  0.67370888],\r\n                          [ 0.4994    ,  0.76396776],\r\n                          [ 0.43026776,  0.8331    ],\r\n                          [ 0.23603224,  0.8331    ],\r\n                          [ 0.1669    ,  0.76396776],\r\n                          [ 0.1669    ,  0.23603224],\r\n                          [ 0.23603224,  0.1669    ],\r\n                          [ 0.43026776,  0.1669    ],\r\n                          [ 0.4994    ,  0.23603224],\r\n                          [ 0.4994    ,  0.32629112]])\r\npoly = gdspy.Polygon(c_coords)\r\ncell.add(poly)\r\noffset_result = gdspy.offset(gdspy.CellReference(cell), distance=0.1)\r\noffset_cell = gdspy.Cell('CELL_OFFSET')\r\noffset_cell.add(offset_result)\r\n\r\ngdspy.LayoutViewer(cells=[offset_cell])\r\n```\r\n\r\nFor distance=0.1 (as above), the offset method returns the expected result. The moment the C-shape \"closes\" upon itself (distance >= 0.18), the call returns SIGSEGV. \r\n\r\nCould you please suggest what can be done to avoid this? One workaround would be to break the shape into multiple polygons, but it is not a generic solution. Thank you.  \r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/heitzmann/gdspy/issues/comments/177003382","html_url":"https://github.com/heitzmann/gdspy/issues/3#issuecomment-177003382","issue_url":"https://api.github.com/repos/heitzmann/gdspy/issues/3","id":177003382,"user":{"login":"rosivda","id":11862627,"avatar_url":"https://avatars.githubusercontent.com/u/11862627?v=3","gravatar_id":"","url":"https://api.github.com/users/rosivda","html_url":"https://github.com/rosivda","followers_url":"https://api.github.com/users/rosivda/followers","following_url":"https://api.github.com/users/rosivda/following{/other_user}","gists_url":"https://api.github.com/users/rosivda/gists{/gist_id}","starred_url":"https://api.github.com/users/rosivda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rosivda/subscriptions","organizations_url":"https://api.github.com/users/rosivda/orgs","repos_url":"https://api.github.com/users/rosivda/repos","events_url":"https://api.github.com/users/rosivda/events{/privacy}","received_events_url":"https://api.github.com/users/rosivda/received_events","type":"User","site_admin":false},"created_at":"2016-01-29T22:43:03Z","updated_at":"2016-01-29T22:43:03Z","body":"Furthermore to @okianus comment above (and related to issue #1), gdspy offset algorithm does not have an expected behavior. For example, suppose we have two structures that are initially separated but, for a sufficiently large offset number, would merge into a single structure. That is not what is happening, as the gdspy offset method treats each structure separately and enlarges them individually, but only if they are simple, preferably convex hull shapes. Knowing this, one of the solutions to @okianus problem is to fragment complex shapes into a set of simpler shapes and subsequently using 'OR' to unite the shapes. This is not a generic solution though. Because of this gdspy offset algorithm limitations, we are forced to deploy external algorithms for our production layouts that handle arbitrary shapes and unite them into a smaller set of resulting shapes. One note here is that we use offsets not only to make small adjustments to the shape but also to produce large exclusion zones for further boolean operations. It often happens that the amount of offset exceeds the size of the feature, which is exactly when gdspy offset algorithm fails, as demonstrated in @okianus  example."}}