Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .gds.gz support to read_gds() and shape tags and layer tags filtering to read_oas() #286

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 71 additions & 5 deletions include/gdstk/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,66 @@ template <class T>
struct Array {
uint64_t capacity; // allocated capacity
uint64_t count; // number of slots used
T* items; // slots
T* items = nullptr; // slots

T& operator[](uint64_t idx) { return items[idx]; }
const T& operator[](uint64_t idx) const { return items[idx]; }

~Array() {
clear();
}
Array() {
capacity = 0;
count = 0;
items = nullptr;
}
Array(const Array<T>& _array) {
capacity = 0;
count = 0;
items = nullptr;
copy_from(_array);
}

Array(Array<T>&& _array) {
capacity = _array.capacity;
count = _array.count;
items = _array.items;
_array.items = nullptr;
_array.capacity = 0;
_array.count = 0;
}

template<typename Number>
Array(Number _capacity, Number _count, T* _item) {
capacity = 0;
count = 0;
ensure_slots((std::max)((uint64_t)_capacity,(uint64_t)_count));
if (_count == 1) {
items[0] = *_item;
}
else {
for (Number i = 0; i < _count; i++) {
items[i] = _item[i];
}
}
}
Array<T>& operator = (Array<T>&& _array) {
if (this == &_array)return *this;
clear();
capacity = _array.capacity;
count = _array.count;
items = _array.items;
_array.items = nullptr;
_array.capacity = 0;
_array.count = 0;
return *this;
}

Array<T>& operator = (const Array<T>& _array) {
if (this == &_array)return *this;
copy_from(_array);
return *this;
}
void print(bool all) const {
printf("Array <%p>, count %" PRIu64 "/%" PRIu64 "\n", this, count, capacity);
if (all && count > 0) {
Expand All @@ -45,10 +100,13 @@ struct Array {
}
}

void clear() {
if (items) free_allocation(items);
items = NULL;
capacity = 0;
void clear(bool deallocate = true) {
if (deallocate)
{
if (items) free_allocation(items);
items = NULL;
capacity = 0;
}
count = 0;
}

Expand Down Expand Up @@ -126,6 +184,14 @@ struct Array {

// The instance should be zeroed before copy_from
void copy_from(const Array<T>& src) {
if (capacity > src.count && src.count>0) {
//enought capacity to just copy
count = src.count;
memcpy(items, src.items, sizeof(T) * count);
return;
}
// need to re allocate
clear();
capacity = src.count;
count = src.count;
if (count > 0) {
Expand Down
6 changes: 5 additions & 1 deletion include/gdstk/cell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
#include "set.hpp"
#include "style.hpp"
#include "tagmap.hpp"
#include <set>

namespace gdstk {

Expand Down Expand Up @@ -139,6 +140,8 @@ struct Cell {
// is true, only polygons with the indicated tag are appended.
void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth, bool filter,
Tag tag, Array<Polygon*>& result) const;
void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth,
std::set<Tag>* _tags, Array<Polygon*>& result) const;

// Similar to get_polygons, but for paths and labels.
void get_flexpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
Expand All @@ -147,7 +150,8 @@ struct Cell {
Array<RobustPath*>& result) const;
void get_labels(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
Array<Label*>& result) const;

void get_labels(bool apply_repetitions, int64_t depth, std::set<Tag>* _tags,
Array<Label*>& result) const;
// Insert all dependencies in result. Dependencies are cells that appear
// in this cell's references. If recursive, include the whole dependency
// tree (dependencies of dependencies).
Expand Down
2 changes: 2 additions & 0 deletions include/gdstk/flexpath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
#define _USE_MATH_DEFINES

#include <stdint.h>
#include <set>

#include "array.hpp"
#include "curve.hpp"
Expand Down Expand Up @@ -153,6 +154,7 @@ struct FlexPath {
// Overlapping points are removed from the path before any processing is
// executed.
ErrorCode to_polygons(bool filter, Tag tag, Array<Polygon*>& result);
ErrorCode to_polygons(const std::set<Tag>* _tags, Array<Polygon*>& result);

// Calculate the center of an element of this path and append the resulting
// curve to result.
Expand Down
2 changes: 1 addition & 1 deletion include/gdstk/gdsii.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ double gdsii_real_to_double(uint64_t real);
// Read a record and swaps only first 2 bytes (record length). The size of the
// buffer must be passed in buffer_count. On return, the record length
// (including header) is returned in buffer_count.
ErrorCode gdsii_read_record(FILE* in, uint8_t* buffer, uint64_t& buffer_count);
ErrorCode gdsii_read_record(FileWrapper* in, uint8_t* buffer, uint64_t& buffer_count);

} // namespace gdstk

Expand Down
26 changes: 24 additions & 2 deletions include/gdstk/library.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,39 @@ struct LibraryInfo {
// tags will be imported. If not NULL, any errors will be reported through
// error_code.
Library read_gds(const char* filename, double unit, double tolerance, const Set<Tag>* shape_tags,
const Set<Tag>* label_tags,
ErrorCode* error_code);

Library read_gds(const char* filename, double unit, double tolerance, const Set<Tag>* shape_tags,
ErrorCode* error_code)
{
return read_gds(filename, unit, tolerance, shape_tags, NULL, error_code);
}

Library read_gds2(const char* filename, double unit, double tolerance, ErrorCode* error_code);

// Read the contents of an OASIS file into a new library. If unit is not zero,
// the units in the file are converted (all elements are properly scaled to the
// desired unit). The value of tolerance is used as the default tolerance for
// paths in the library and for the creation of circles. If shape_tags is not
// empty, only shapes in those tags will be imported. If not NULL, any errors
// will be reported through error_code.
Library read_oas(const char* filename, double unit,
double tolerance, // TODO: const Set<Tag>* shape_tags,
ErrorCode* error_code);
double tolerance,
const Set<Tag>* shape_tags,
const Set<Tag>* label_tags,
ErrorCode* error_code,
Tag fub_tag, double min_fub_dimension);

Library read_oas(const char* filename, double unit,
double tolerance,
const Set<Tag>* shape_tags,
const Set<Tag>* label_tags,
ErrorCode* error_code);

Library read_oas(const char* filename, double unit,
double tolerance,
ErrorCode* error_code);

// Read the unit and precision of a GDSII file and return in the respective
// arguments.
Expand Down
21 changes: 20 additions & 1 deletion include/gdstk/oasis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
#include "map.hpp"
#include "repetition.hpp"
#include "utils.hpp"
#include "label.hpp"

namespace gdstk {

Expand Down Expand Up @@ -166,16 +167,26 @@ struct OasisState {

ErrorCode oasis_read(void* buffer, size_t size, size_t count, OasisStream& in);

ErrorCode oasis_skip(size_t size, size_t count, OasisStream& in);

size_t oasis_write(const void* buffer, size_t size, size_t count, OasisStream& out);

int oasis_putc(int c, OasisStream& out);

uint8_t* oasis_read_string(OasisStream& in, bool append_terminating_null, uint64_t& len);

void oasis_read_string2(OasisStream& in, Label* dest, uint64_t capacity, uint64_t& count);

ErrorCode oasis_skip_string(OasisStream& in);

uint64_t oasis_read_unsigned_integer(OasisStream& in);

ErrorCode oasis_skip_unsigned_integer(OasisStream& in);

int64_t oasis_read_integer(OasisStream& in);

ErrorCode oasis_skip_integer(OasisStream& in);

inline int64_t oasis_read_1delta(OasisStream& in) { return oasis_read_integer(in); };

void oasis_read_2delta(OasisStream& in, int64_t& x, int64_t& y);
Expand All @@ -184,8 +195,12 @@ void oasis_read_3delta(OasisStream& in, int64_t& x, int64_t& y);

void oasis_read_gdelta(OasisStream& in, int64_t& x, int64_t& y);

ErrorCode oasis_skip_gdelta(OasisStream& in);

double oasis_read_real_by_type(OasisStream& in, OasisDataType type);

ErrorCode oasis_skip_real_by_type(OasisStream& in, OasisDataType type);

inline double oasis_read_real(OasisStream& in) {
OasisDataType type;
if (oasis_read(&type, 1, 1, in) != ErrorCode::NoError) return 0;
Expand All @@ -197,8 +212,12 @@ inline double oasis_read_real(OasisStream& in) {
// be an implicit extra delta for Manhattan types).
uint64_t oasis_read_point_list(OasisStream& in, double scaling, bool closed, Array<Vec2>& result);

ErrorCode oasis_skip_point_list(OasisStream& in);

void oasis_read_repetition(OasisStream& in, double scaling, Repetition& repetition);

ErrorCode oasis_skip_repetition(OasisStream& in);

void oasis_write_unsigned_integer(OasisStream& out, uint64_t value);

void oasis_write_integer(OasisStream& out, int64_t value);
Expand All @@ -223,7 +242,7 @@ void oasis_write_point_list(OasisStream& out, const Array<Vec2> points, double s
bool closed);

// This should only be called with repetition.get_count() > 1
void oasis_write_repetition(OasisStream& out, const Repetition repetition, double scaling);
void oasis_write_repetition(OasisStream& out, const Repetition &repetition, double scaling);

} // namespace gdstk

Expand Down
26 changes: 26 additions & 0 deletions include/gdstk/polygon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@ struct Polygon {
Array<Vec2> point_array;
Repetition repetition;
Property* properties;

Polygon() { properties = nullptr; }
Polygon& operator=(Polygon&& _p) {
if (this == &_p) return *this;
point_array.clear();
repetition.clear();
if (properties) {
properties_clear(properties);
}
tag = _p.tag;
point_array = std::move(_p.point_array);
repetition = std::move(_p.repetition);
properties = _p.properties;
_p.properties = nullptr;
return *this;
}

Polygon(Polygon&& _p) {
tag = _p.tag;
point_array = std::move(_p.point_array);
repetition = std::move(_p.repetition);
properties = _p.properties;
_p.properties = nullptr;
}
~Polygon() { clear(); }

// Used by the python interface to store the associated PyObject* (if any).
// No functions in gdstk namespace should touch this value!
void* owner;
Expand Down
12 changes: 3 additions & 9 deletions include/gdstk/rawcell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,13 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
namespace gdstk {

struct RawSource {
FILE* file;
FileWrapper* file;
uint32_t uses;

// Read num_bytes into buffer from fd starting at offset
int64_t offset_read(void* buffer, uint64_t num_bytes, uint64_t offset) const {
#ifdef _WIN32
// The POSIX version (pread) does not change the file cursor, this
// does. Furthermore, this is not thread-safe!
FSEEK64(file, offset, SEEK_SET);
return fread(buffer, 1, num_bytes, file);
#else
return pread(fileno(file), buffer, num_bytes, offset);
#endif
file->Seek(offset, SEEK_SET);
return file->Read(buffer, 1, num_bytes);
};
};

Expand Down
6 changes: 5 additions & 1 deletion include/gdstk/reference.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>

#include <stdint.h>
#include <stdio.h>
#include <set>

#include "flexpath.hpp"
#include "label.hpp"
Expand Down Expand Up @@ -107,13 +108,16 @@ struct Reference {
// created.
void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth, bool filter,
Tag tag, Array<Polygon*>& result) const;
void get_polygons(bool apply_repetitions, bool include_paths, int64_t depth,
std::set<Tag>* _tags, Array<Polygon*>& result) const;
void get_flexpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
Array<FlexPath*>& result) const;
void get_robustpaths(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
Array<RobustPath*>& result) const;
void get_labels(bool apply_repetitions, int64_t depth, bool filter, Tag tag,
Array<Label*>& result) const;

void get_labels(bool apply_repetitions, int64_t depth, std::set<Tag>* _tags,
Array<Label*>& result) const;
// These functions output the reference in the GDSII and SVG formats. They
// are not supposed to be called by the user.
ErrorCode to_gds(FILE* out, double scaling) const;
Expand Down
Loading