mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-08 04:08:14 +02:00
Merge branch 'master' into macos-build-on-master
This commit is contained in:
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+148
@@ -0,0 +1,148 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
if !$:.member?(File::dirname($0))
|
||||
$:.push(File::dirname($0))
|
||||
end
|
||||
|
||||
load("test_prologue.rb")
|
||||
|
||||
# Tests for the klayout executable
|
||||
#
|
||||
# This tests actually runs inside a KLayout/unit_tests instance but
|
||||
# only for providing the test automation.
|
||||
|
||||
class KLayoutMain_TestClass < TestBase
|
||||
|
||||
def test_1
|
||||
|
||||
# Basic
|
||||
version = `./klayout -v`
|
||||
assert_equal(version, "#{RBA::Application.instance.version}\n")
|
||||
|
||||
end
|
||||
|
||||
def test_2
|
||||
|
||||
# Basic Ruby
|
||||
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.rb")}`
|
||||
assert_equal(out, "Variable v1=42 v2=hello\n")
|
||||
|
||||
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.rb")} -rm #{File.join(File.dirname(__FILE__), "test2.rb")} -rm #{File.join(File.dirname(__FILE__), "test3.rb")}`
|
||||
assert_equal(out, "test2\ntest3\nVariable v1=42 v2=hello\n")
|
||||
|
||||
end
|
||||
|
||||
def test_3
|
||||
|
||||
# Basic Python
|
||||
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.py")}`
|
||||
assert_equal(out, "Variable v1=42 v2=hello\n")
|
||||
|
||||
end
|
||||
|
||||
def test_4
|
||||
|
||||
# Application class
|
||||
|
||||
# QCoreApplication for (headless) mode
|
||||
out = `./klayout -b -r #{File.join(File.dirname(__FILE__), "test_app.rb")}`
|
||||
assert_equal(out, "RBA::Application superclass RBA::QCoreApplication_Native\nMainWindow is not there\n")
|
||||
|
||||
# QApplication for GUI mode
|
||||
out = `./klayout -z -nc -rx -r #{File.join(File.dirname(__FILE__), "test_app.rb")}`
|
||||
assert_equal(out, "RBA::Application superclass RBA::QApplication_Native\nMainWindow is there\n")
|
||||
|
||||
end
|
||||
|
||||
def test_5
|
||||
|
||||
# Script variables
|
||||
out = `./klayout -b -wd tv1=17 -wd tv2=25 -wd tv3 -r #{File.join(File.dirname(__FILE__), "test_script.rb")}`
|
||||
assert_equal(out, "42\ntrue\n")
|
||||
|
||||
end
|
||||
|
||||
def test_6
|
||||
|
||||
# Editable / Non-editable mode
|
||||
out = `./klayout -b -ne -r #{File.join(File.dirname(__FILE__), "test_em.rb")}`
|
||||
assert_equal(out, "false\n")
|
||||
|
||||
out = `./klayout -b -e -r #{File.join(File.dirname(__FILE__), "test_em.rb")}`
|
||||
assert_equal(out, "true\n")
|
||||
|
||||
end
|
||||
|
||||
def test_7
|
||||
|
||||
cfg_file = File.join($ut_testtmp, "config.xml")
|
||||
File.open(cfg_file, "w") { |file| file.puts("<config/>") }
|
||||
|
||||
# Special configuration file
|
||||
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config1.rb")}`
|
||||
|
||||
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
|
||||
assert_equal(out, "42\n")
|
||||
|
||||
# Update
|
||||
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config2.rb")}`
|
||||
|
||||
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
|
||||
assert_equal(out, "17\n")
|
||||
|
||||
# Reset
|
||||
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config1.rb")}`
|
||||
|
||||
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
|
||||
assert_equal(out, "42\n")
|
||||
|
||||
# No update
|
||||
`./klayout -b -t -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config2.rb")}`
|
||||
|
||||
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
|
||||
assert_equal(out, "42\n")
|
||||
|
||||
end
|
||||
|
||||
def test_8
|
||||
|
||||
# Loading layouts
|
||||
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} -r #{File.join(File.dirname(__FILE__), "test_lay.rb")}`
|
||||
assert_equal(out, "TOP1\n")
|
||||
|
||||
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} #{File.join(File.dirname(__FILE__), "test2.gds")} -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
|
||||
assert_equal(out, "TOP1\nTOP2\n")
|
||||
|
||||
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} #{File.join(File.dirname(__FILE__), "test2.gds")} -s -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
|
||||
assert_equal(out, "TOP1;TOP2\n")
|
||||
|
||||
end
|
||||
|
||||
def test_9
|
||||
|
||||
# Sessions
|
||||
out = `./klayout -z -nc -rx -u #{File.join(File.dirname(__FILE__), "session.lys")} -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
|
||||
assert_equal(out, "TOP2;TOP1\n")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
Vendored
+214
@@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<session>
|
||||
<window-width>1392</window-width>
|
||||
<window-height>912</window-height>
|
||||
<window-state>AAAA/wAAAAD9AAAAAgAAAAAAAAC5AAADLvwCAAAAAvsAAAAqAG4AYQB2AGkAZwBhAHQAbwByAF8AZABvAGMAawBfAHcAaQBkAGcAZQB0AAAAAAD/////AAAAkgD////7AAAAHABoAHAAXwBkAG8AYwBrAF8AdwBpAGQAZwBlAHQBAAAATAAAAy4AAAAZAP///wAAAAEAAAEdAAADLvwCAAAAAvsAAAAcAGwAcABfAGQAbwBjAGsAXwB3AGkAZABnAGUAdAEAAABMAAACnQAAABkA////+wAAABwAbAB0AF8AZABvAGMAawBfAHcAaQBkAGcAZQB0AQAAAu8AAACLAAAAiwAAAIsAAAOOAAADLgAAAAQAAAAEAAAACAAAAAj8AAAAAQAAAAIAAAABAAAADgB0AG8AbwBsAGIAYQByAQAAAAD/////AAAAAAAAAAA=</window-state>
|
||||
<window-geometry>AdnQywABAAAAAAEpAAAAFQAABq4AAAPSAAABNAAAADgAAAajAAADxwAAAAAAAA==</window-geometry>
|
||||
<current-view>0</current-view>
|
||||
<layout>
|
||||
<name>test1.gds</name>
|
||||
<file-path>test1.gds</file-path>
|
||||
<save-options-valid>false</save-options-valid>
|
||||
<save-options>
|
||||
<oasis>
|
||||
<compression-level>2</compression-level>
|
||||
<write-cblocks>false</write-cblocks>
|
||||
<strict-mode>false</strict-mode>
|
||||
<write-std-properties>1</write-std-properties>
|
||||
<subst-char>*</subst-char>
|
||||
<permissive>false</permissive>
|
||||
</oasis>
|
||||
<gds2>
|
||||
<write-timestamps>true</write-timestamps>
|
||||
<write-cell-properties>false</write-cell-properties>
|
||||
<write-file-properties>false</write-file-properties>
|
||||
<no-zero-length-paths>false</no-zero-length-paths>
|
||||
<multi-xy-records>false</multi-xy-records>
|
||||
<max-vertex-count>8000</max-vertex-count>
|
||||
<max-cellname-length>32000</max-cellname-length>
|
||||
<libname>LIB</libname>
|
||||
</gds2>
|
||||
<cif>
|
||||
<polygon-mode>0</polygon-mode>
|
||||
</cif>
|
||||
<cif>
|
||||
<dummy-calls>false</dummy-calls>
|
||||
<blank-separator>false</blank-separator>
|
||||
</cif>
|
||||
</save-options>
|
||||
<load-options>
|
||||
<common>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
<enable-properties>true</enable-properties>
|
||||
<enable-text-objects>true</enable-text-objects>
|
||||
</common>
|
||||
<gds2>
|
||||
<box-mode>1</box-mode>
|
||||
<allow-big-records>true</allow-big-records>
|
||||
<allow-multi-xy-records>true</allow-multi-xy-records>
|
||||
</gds2>
|
||||
<dxf>
|
||||
<dbu>0.001</dbu>
|
||||
<unit>1</unit>
|
||||
<text-scaling>100</text-scaling>
|
||||
<circle-points>100</circle-points>
|
||||
<circle-accuracy>0</circle-accuracy>
|
||||
<polyline-mode>0</polyline-mode>
|
||||
<render-texts-as-polygons>false</render-texts-as-polygons>
|
||||
<keep-other-cells>false</keep-other-cells>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
</dxf>
|
||||
<cif>
|
||||
<wire-mode>0</wire-mode>
|
||||
<dbu>0.001</dbu>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
</cif>
|
||||
</load-options>
|
||||
</layout>
|
||||
<layout>
|
||||
<name>test2.gds</name>
|
||||
<file-path>test2.gds</file-path>
|
||||
<save-options-valid>true</save-options-valid>
|
||||
<save-options>
|
||||
<oasis>
|
||||
<compression-level>2</compression-level>
|
||||
<write-cblocks>false</write-cblocks>
|
||||
<strict-mode>false</strict-mode>
|
||||
<write-std-properties>1</write-std-properties>
|
||||
<subst-char>*</subst-char>
|
||||
<permissive>false</permissive>
|
||||
</oasis>
|
||||
<gds2>
|
||||
<write-timestamps>true</write-timestamps>
|
||||
<write-cell-properties>false</write-cell-properties>
|
||||
<write-file-properties>false</write-file-properties>
|
||||
<no-zero-length-paths>false</no-zero-length-paths>
|
||||
<multi-xy-records>false</multi-xy-records>
|
||||
<max-vertex-count>8000</max-vertex-count>
|
||||
<max-cellname-length>32000</max-cellname-length>
|
||||
<libname>LIB</libname>
|
||||
</gds2>
|
||||
<cif>
|
||||
<polygon-mode>0</polygon-mode>
|
||||
</cif>
|
||||
<cif>
|
||||
<dummy-calls>false</dummy-calls>
|
||||
<blank-separator>false</blank-separator>
|
||||
</cif>
|
||||
</save-options>
|
||||
<load-options>
|
||||
<common>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
<enable-properties>true</enable-properties>
|
||||
<enable-text-objects>true</enable-text-objects>
|
||||
</common>
|
||||
<gds2>
|
||||
<box-mode>1</box-mode>
|
||||
<allow-big-records>true</allow-big-records>
|
||||
<allow-multi-xy-records>true</allow-multi-xy-records>
|
||||
</gds2>
|
||||
<dxf>
|
||||
<dbu>0.001</dbu>
|
||||
<unit>1</unit>
|
||||
<text-scaling>100</text-scaling>
|
||||
<circle-points>100</circle-points>
|
||||
<circle-accuracy>0</circle-accuracy>
|
||||
<polyline-mode>0</polyline-mode>
|
||||
<render-texts-as-polygons>false</render-texts-as-polygons>
|
||||
<keep-other-cells>false</keep-other-cells>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
</dxf>
|
||||
<cif>
|
||||
<wire-mode>0</wire-mode>
|
||||
<dbu>0.001</dbu>
|
||||
<layer-map>layer_map()</layer-map>
|
||||
<create-other-layers>true</create-other-layers>
|
||||
</cif>
|
||||
</load-options>
|
||||
</layout>
|
||||
<view>
|
||||
<title/>
|
||||
<active-cellview-index>1</active-cellview-index>
|
||||
<display>
|
||||
<x-left>-0.892701664533</x-left>
|
||||
<x-right>8.8947503201</x-right>
|
||||
<y-bottom>-0.204353393086</y-bottom>
|
||||
<y-top>8.19564660691</y-top>
|
||||
<min-hier>0</min-hier>
|
||||
<max-hier>1</max-hier>
|
||||
<cellpaths>
|
||||
<cellpath>
|
||||
<cellname>TOP2</cellname>
|
||||
</cellpath>
|
||||
<cellpath>
|
||||
<cellname>TOP1</cellname>
|
||||
</cellpath>
|
||||
</cellpaths>
|
||||
</display>
|
||||
<cellviews>
|
||||
<cellview>
|
||||
<layout-ref>test2.gds</layout-ref>
|
||||
<tech-name/>
|
||||
<hidden-cells>
|
||||
</hidden-cells>
|
||||
</cellview>
|
||||
<cellview>
|
||||
<layout-ref>test1.gds</layout-ref>
|
||||
<tech-name/>
|
||||
<hidden-cells>
|
||||
</hidden-cells>
|
||||
</cellview>
|
||||
</cellviews>
|
||||
<bookmarks>
|
||||
</bookmarks>
|
||||
<rdb-files>
|
||||
</rdb-files>
|
||||
<current-layer-property-tab>0</current-layer-property-tab>
|
||||
<layer-properties-tabs>
|
||||
<layer-properties>
|
||||
<properties>
|
||||
<frame-color>#ff80a8</frame-color>
|
||||
<fill-color>#ff80a8</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I9</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name/>
|
||||
<source>2/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#ff80a8</frame-color>
|
||||
<fill-color>#ff80a8</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I9</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width/>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name/>
|
||||
<source>1/0@2</source>
|
||||
</properties>
|
||||
<name/>
|
||||
</layer-properties>
|
||||
</layer-properties-tabs>
|
||||
<annotations>
|
||||
</annotations>
|
||||
</view>
|
||||
</session>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
print("Variable v1="+str(v1)+" v2="+str(v2))
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts "Variable v1=#{$v1} v2=#{$v2}"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts "test2"
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts "test3"
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
puts "RBA::Application superclass " + RBA::Application.instance.class.superclass.to_s
|
||||
puts "MainWindow is " + (RBA::Application.instance.main_window ? "there" : "not there")
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts RBA::Application.instance.is_editable?.inspect
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
|
||||
# In the test environment, we cannot make sure that we destroy the ruby interpreter before the RBA
|
||||
# environment is shut down. Therefore we must release all RBA objects by explicitly calling the GC
|
||||
# and start the test suite manually.
|
||||
|
||||
err = 0
|
||||
any = nil
|
||||
repeat = (ENV["TESTREPEAT"] || "1").to_i
|
||||
|
||||
class MyTestRunner < Test::Unit::UI::Console::TestRunner
|
||||
def initialize(suite, *args)
|
||||
super(suite, *args)
|
||||
end
|
||||
def test_started(name)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
Object.constants.each do |c|
|
||||
if c.to_s =~ /_TestClass$/
|
||||
repeat.times do
|
||||
r = MyTestRunner::new(Object.const_get(c)).start
|
||||
err += r.error_count + r.failure_count
|
||||
end
|
||||
any = true
|
||||
end
|
||||
end
|
||||
|
||||
if !any
|
||||
raise("No test class defined (any ending with _TestClass)")
|
||||
end
|
||||
|
||||
if err > 0
|
||||
raise("Tests failed (#{err} Errors + Failures)")
|
||||
end
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts RBA::LayoutView::current.active_cellview.layout.top_cell.name
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
|
||||
RBA::Application::instance.main_window.views.times do |v|
|
||||
view = RBA::Application::instance.main_window.view(v)
|
||||
tc = []
|
||||
view.cellviews.times { |cv| tc << view.cellview(cv).layout.top_cell.name }
|
||||
puts tc.join(";")
|
||||
end
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
|
||||
# in MSVC environment:
|
||||
if ENV["RUBY"]
|
||||
ruby_libs = "#{ENV["RUBY"]}/lib/ruby/#{RUBY_VERSION}"
|
||||
if !$:.member?(ruby_libs)
|
||||
$:.push(ruby_libs)
|
||||
end
|
||||
end
|
||||
|
||||
# Set this to true to disable some tests involving exceptions
|
||||
$leak_check = ENV["TEST_LEAK_CHECK"]
|
||||
|
||||
# Fetch location of source files and the temp files
|
||||
$ut_testsrc = ENV["TESTSRC"] || raise("Environment variable $TESTSRC not set")
|
||||
$ut_testtmp = ENV["TESTTMP_WITH_NAME"] || ENV["TESTTMP"] || raise("Environment variable $TESTTMP not set")
|
||||
|
||||
# Pull packages from vendor drop-in
|
||||
vendor = File.join($ut_testsrc, "testdata", "vendor", "ruby")
|
||||
if !$:.member?(vendor)
|
||||
$:.unshift(vendor)
|
||||
end
|
||||
|
||||
# Require Test::Unit
|
||||
require 'test/unit/ui/console/testrunner'
|
||||
|
||||
# TestBase is an alias for "TestCase"
|
||||
Object.const_defined?(:TestBase) && Object.send(:remove_const, :TestBase)
|
||||
TestBase = Test::Unit::TestCase
|
||||
|
||||
# undefine existing classes
|
||||
|
||||
Object.constants.each do |c|
|
||||
if c.to_s =~ /_TestClass$/
|
||||
Object.send(:remove_const, c)
|
||||
end
|
||||
end
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
puts RBA::Application.instance.get_config("key4test")
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
|
||||
puts RBA::Expression::new("to_i(tv1)+to_i(tv2)").eval
|
||||
puts RBA::Expression::new("tv3").eval
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
RBA::Application.instance.set_config("key4test", "42")
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
RBA::Application.instance.set_config("key4test", "17")
|
||||
|
||||
Vendored
+33
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -114,6 +114,22 @@ def map2str(dict):
|
||||
strings.append(str(x) + ": " + str(dict[x]))
|
||||
return "{" + ", ".join(strings) + "}"
|
||||
|
||||
class PyGObject(pya.GObject):
|
||||
z = -1
|
||||
def __init__(self, z):
|
||||
super(PyGObject, self).__init__()
|
||||
self.z = z
|
||||
# reimplementation of "virtual int g()"
|
||||
def g(self):
|
||||
return self.z*2
|
||||
|
||||
class PyGFactory(pya.GFactory):
|
||||
def __init__(self):
|
||||
super(PyGFactory, self).__init__()
|
||||
# reimplementation of "virtual GObject *f(int)"
|
||||
def f(self, z):
|
||||
return PyGObject(z)
|
||||
|
||||
class BasicTest(unittest.TestCase):
|
||||
|
||||
def test_00(self):
|
||||
@@ -124,6 +140,11 @@ class BasicTest(unittest.TestCase):
|
||||
a = pya.A.new_a(100)
|
||||
self.assertEqual( pya.A.a0(), ac0 + 1 )
|
||||
|
||||
a = pya.A()
|
||||
self.assertEqual(a.a1(), 17)
|
||||
a.assign(pya.A(110))
|
||||
self.assertEqual(a.a1(), 110)
|
||||
|
||||
a = None
|
||||
self.assertEqual( pya.A.a0(), ac0 )
|
||||
|
||||
@@ -2674,6 +2695,17 @@ class BasicTest(unittest.TestCase):
|
||||
self.assertEqual(sc.got_s0a, 0)
|
||||
self.assertEqual(sc.got_s0b, 0)
|
||||
|
||||
# Custom factory implemented in Python
|
||||
def test_80(self):
|
||||
gc = pya.GObject.g_inst_count()
|
||||
gf = PyGFactory()
|
||||
go = pya.GFactory.create_f(gf, 17)
|
||||
self.assertEqual(go.g_virtual(), 34)
|
||||
self.assertEqual(go.g_org(), 0)
|
||||
self.assertEqual(pya.GObject.g_inst_count(), gc + 1)
|
||||
go = None
|
||||
self.assertEqual(pya.GObject.g_inst_count(), gc)
|
||||
|
||||
# run unit tests
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+731
@@ -0,0 +1,731 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import pya
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
class DBPolygonTests(unittest.TestCase):
|
||||
|
||||
# DPolygon basics
|
||||
def test_1_DPolygon(self):
|
||||
|
||||
a = pya.DPolygon()
|
||||
self.assertEqual( str(a), "()" )
|
||||
self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.is_box(), False )
|
||||
|
||||
b = a.dup()
|
||||
a = pya.DPolygon( [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 5 ), pya.DPoint( 5, 5 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;5,5)" )
|
||||
self.assertEqual( str(a * 2), "(0,2;2,10;10,10)" )
|
||||
self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.is_box(), False )
|
||||
self.assertEqual( a.num_points_hull(), 3 )
|
||||
c = a.dup()
|
||||
|
||||
self.assertEqual( a == b, False )
|
||||
self.assertEqual( a == c, True )
|
||||
self.assertEqual( a != b, True )
|
||||
self.assertEqual( a != c, False )
|
||||
|
||||
a = pya.DPolygon( pya.DBox( 5, -10, 20, 15 ) )
|
||||
self.assertEqual( a.is_box(), True )
|
||||
self.assertEqual( str(a), "(5,-10;5,15;20,15;20,-10)" )
|
||||
self.assertEqual( str(pya.Polygon(a)), "(5,-10;5,15;20,15;20,-10)" )
|
||||
self.assertEqual( a.num_points_hull(), 4 )
|
||||
self.assertEqual( a.area(), 15*25 )
|
||||
self.assertEqual( a.perimeter(), 80 )
|
||||
self.assertEqual( a.inside( pya.DPoint( 10, 0 ) ), True )
|
||||
self.assertEqual( a.inside( pya.DPoint( 5, 0 ) ), True )
|
||||
self.assertEqual( a.inside( pya.DPoint( 30, 0 ) ), False )
|
||||
|
||||
arr = []
|
||||
for p in a.each_point_hull():
|
||||
arr.append( str(p) )
|
||||
self.assertEqual( arr, ["5,-10", "5,15", "20,15", "20,-10"] )
|
||||
|
||||
b = a.dup()
|
||||
|
||||
self.assertEqual( str(a.moved( pya.DPoint( 0, 1 ) )), "(5,-9;5,16;20,16;20,-9)" )
|
||||
self.assertEqual( str(a.moved( 0, 1 )), "(5,-9;5,16;20,16;20,-9)" )
|
||||
aa = a.dup()
|
||||
aa.move( 1, 0 )
|
||||
self.assertEqual( str(aa), "(6,-10;6,15;21,15;21,-10)" )
|
||||
a.move( pya.DPoint( 1, 0 ) )
|
||||
self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" )
|
||||
|
||||
b = b.transformed( pya.DTrans( pya.DTrans.R0, pya.DPoint( 1, 0 )) )
|
||||
self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" )
|
||||
|
||||
m = pya.DCplxTrans( pya.DTrans(), 1.5 )
|
||||
self.assertEqual( type(a.transformed(m)).__name__, "DPolygon" )
|
||||
self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" )
|
||||
|
||||
m = pya.VCplxTrans( 1000.0 )
|
||||
self.assertEqual( type(a.transformed(m)).__name__, "Polygon" )
|
||||
self.assertEqual( str(a.transformed(m)), "(6000,-10000;6000,15000;21000,15000;21000,-10000)" )
|
||||
|
||||
a.hull = [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 1 ), pya.DPoint( 1, 5 ) ]
|
||||
self.assertEqual( str(a.bbox()), "(0,1;1,5)" )
|
||||
|
||||
self.assertEqual( a.holes(), 0 )
|
||||
a.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.area(), 0 )
|
||||
self.assertEqual( a.num_points_hole(0), 3 )
|
||||
self.assertEqual( a.holes(), 1 )
|
||||
self.assertEqual( str(a.point_hull(1)), "1,5" )
|
||||
self.assertEqual( str(a.point_hull(0)), "0,1" )
|
||||
self.assertEqual( str(a.point_hull(100)), "0,0" )
|
||||
self.assertEqual( str(a.point_hole(0, 100)), "0,0" )
|
||||
self.assertEqual( str(a.point_hole(0, 1)), "2,2" )
|
||||
self.assertEqual( str(a.point_hole(1, 1)), "0,0" )
|
||||
a.compress(False);
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
a.compress(True);
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
|
||||
b = a.dup()
|
||||
b.assign_hole(0, pya.DBox( 10, 20, 20, 60 ))
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" )
|
||||
b.insert_hole(pya.DBox( 10, 20, 20, 60 ))
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60/10,20;20,20;20,60;10,60)" )
|
||||
self.assertEqual( b.is_box(), False )
|
||||
|
||||
b = a.dup()
|
||||
b.assign_hole(0, [ pya.DPoint( 10, 20 ), pya.DPoint( 20, 20 ), pya.DPoint( 20, 60 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
|
||||
b.assign_hole(1, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
|
||||
b.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/1,2;2,2;2,6/10,20;20,20;20,60)" )
|
||||
b.assign_hole(0, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/15,25;25,25;25,65/10,20;20,20;20,60)" )
|
||||
|
||||
arr = []
|
||||
for p in a.each_point_hole(0):
|
||||
arr.append( str(p) )
|
||||
|
||||
self.assertEqual( arr, ["1,2", "2,2", "2,6"] )
|
||||
|
||||
arr = []
|
||||
for p in a.each_edge():
|
||||
arr.append( str(p) )
|
||||
self.assertEqual( arr, ["(0,1;1,5)", "(1,5;1,1)", "(1,1;0,1)", "(1,2;2,2)", "(2,2;2,6)", "(2,6;1,2)"] )
|
||||
|
||||
# Ellipse constructor
|
||||
p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 200 )
|
||||
self.assertEqual(p.num_points(), 200)
|
||||
self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)")
|
||||
self.assertEqual(int(p.area()), 1884645544) # roughly box.area*PI/4
|
||||
|
||||
p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 4 )
|
||||
self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
|
||||
|
||||
# Polygon basics
|
||||
def test_1_Polygon(self):
|
||||
|
||||
a = pya.Polygon()
|
||||
self.assertEqual( str(a), "()" )
|
||||
self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.is_box(), False )
|
||||
|
||||
b = a.dup()
|
||||
a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;5,5)" )
|
||||
self.assertEqual( str(a * 2), "(0,2;2,10;10,10)" )
|
||||
self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.num_points_hull(), 3 )
|
||||
c = a.dup()
|
||||
|
||||
self.assertEqual( a == b, False )
|
||||
self.assertEqual( a == c, True )
|
||||
self.assertEqual( a != b, True )
|
||||
self.assertEqual( a != c, False )
|
||||
|
||||
a = pya.Polygon( pya.Box( 5, -10, 20, 15 ) )
|
||||
self.assertEqual( a.is_box(), True )
|
||||
self.assertEqual( str(a), "(5,-10;5,15;20,15;20,-10)" )
|
||||
self.assertEqual( str(pya.DPolygon(a)), "(5,-10;5,15;20,15;20,-10)" )
|
||||
self.assertEqual( a.num_points_hull(), 4 )
|
||||
self.assertEqual( a.area(), 15*25 )
|
||||
self.assertEqual( a.perimeter(), 80 )
|
||||
self.assertEqual( a.inside( pya.Point( 10, 0 ) ), True )
|
||||
self.assertEqual( a.inside( pya.Point( 5, 0 ) ), True )
|
||||
self.assertEqual( a.inside( pya.Point( 30, 0 ) ), False )
|
||||
|
||||
arr = []
|
||||
for p in a.each_point_hull():
|
||||
arr.append(str(p))
|
||||
self.assertEqual( arr, ["5,-10", "5,15", "20,15", "20,-10"] )
|
||||
|
||||
b = a.dup()
|
||||
|
||||
self.assertEqual( str(a.moved( pya.Point( 0, 1 ) )), "(5,-9;5,16;20,16;20,-9)" )
|
||||
self.assertEqual( str(a.moved( 0, 1 )), "(5,-9;5,16;20,16;20,-9)" )
|
||||
aa = a.dup()
|
||||
aa.move( 1, 0 )
|
||||
self.assertEqual( str(aa), "(6,-10;6,15;21,15;21,-10)" )
|
||||
a.move( pya.Point( 1, 0 ) )
|
||||
self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" )
|
||||
|
||||
b = b.transformed( pya.Trans( pya.Trans.R0, pya.Point( 1, 0 )) )
|
||||
self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" )
|
||||
|
||||
m = pya.CplxTrans( pya.Trans(), 1.5 )
|
||||
self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" )
|
||||
self.assertEqual( str(a.transformed(pya.ICplxTrans(m))), "(9,-15;9,23;32,23;32,-15)" )
|
||||
|
||||
a.hull = [ pya.Point( 0, 1 ), pya.Point( 1, 1 ), pya.Point( 1, 5 ) ]
|
||||
self.assertEqual( str(a.bbox()), "(0,1;1,5)" )
|
||||
|
||||
self.assertEqual( a.holes(), 0 )
|
||||
a.insert_hole( [ pya.Point( 1, 2 ), pya.Point( 2, 2 ), pya.Point( 2, 6 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) )
|
||||
self.assertEqual( a.area(), 0 )
|
||||
self.assertEqual( a.num_points_hole(0), 3 )
|
||||
self.assertEqual( a.holes(), 1 )
|
||||
self.assertEqual( str(a.point_hull(1)), "1,5" )
|
||||
self.assertEqual( str(a.point_hull(0)), "0,1" )
|
||||
self.assertEqual( str(a.point_hull(100)), "0,0" )
|
||||
self.assertEqual( str(a.point_hole(0, 100)), "0,0" )
|
||||
self.assertEqual( str(a.point_hole(0, 1)), "2,2" )
|
||||
self.assertEqual( str(a.point_hole(1, 1)), "0,0" )
|
||||
a.compress(False);
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
a.compress(True);
|
||||
self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
|
||||
|
||||
b = a.dup()
|
||||
b.assign_hole(0, pya.Box( 10, 20, 20, 60 ))
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" )
|
||||
self.assertEqual( b.is_box(), False )
|
||||
b.insert_hole(pya.Box( 10, 20, 20, 60 ))
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60/10,20;20,20;20,60;10,60)" )
|
||||
|
||||
b = a.dup()
|
||||
b.assign_hole(0, [ pya.Point( 10, 20 ), pya.Point( 20, 20 ), pya.Point( 20, 60 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
|
||||
b.assign_hole(1, [ pya.Point( 15, 25 ), pya.Point( 25, 25 ), pya.Point( 25, 65 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
|
||||
b.insert_hole( [ pya.Point( 1, 2 ), pya.Point( 2, 2 ), pya.Point( 2, 6 ) ] )
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/1,2;2,2;2,6/10,20;20,20;20,60)" )
|
||||
b.assign_hole(0, [ pya.Point( 15, 25 ), pya.Point( 25, 25 ), pya.Point( 25, 65 ) ])
|
||||
self.assertEqual( str(b), "(0,1;1,5;1,1/15,25;25,25;25,65/10,20;20,20;20,60)" )
|
||||
|
||||
arr = []
|
||||
for p in a.each_point_hole(0):
|
||||
arr.append(str(p))
|
||||
self.assertEqual( arr, ["1,2", "2,2", "2,6"] )
|
||||
|
||||
arr = []
|
||||
for p in a.each_edge():
|
||||
arr.append(str(p))
|
||||
self.assertEqual( arr, ["(0,1;1,5)", "(1,5;1,1)", "(1,1;0,1)", "(1,2;2,2)", "(2,2;2,6)", "(2,6;1,2)"] )
|
||||
|
||||
a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;5,5)" )
|
||||
self.assertEqual( str(a.sized(2)), "(0,-2;-2,0;-1,7;7,7;8,5)" )
|
||||
self.assertEqual( str(a.sized(2, 2)), "(0,-2;-2,0;-1,7;7,7;8,5)" )
|
||||
aa = a.dup()
|
||||
a.size(2, 2)
|
||||
self.assertEqual( str(a), "(0,-2;-2,0;-1,7;7,7;8,5)" )
|
||||
a = aa.dup()
|
||||
a.size(2)
|
||||
self.assertEqual( str(a), "(0,-2;-2,0;-1,7;7,7;8,5)" )
|
||||
|
||||
a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] )
|
||||
self.assertEqual( str(a), "(0,1;1,5;5,5)" )
|
||||
self.assertEqual( str(a.sized(2, 0, 2)), "(-2,1;-1,5;7,5;2,1)" )
|
||||
a.size(2, 0, 2);
|
||||
self.assertEqual( str(a), "(-2,1;-1,5;7,5;2,1)" )
|
||||
|
||||
a = pya.Polygon()
|
||||
self.assertEqual( str(a), "()" )
|
||||
|
||||
# corner rounding
|
||||
a = pya.Polygon( [ pya.Point(0, 0), pya.Point(0, 2000), pya.Point(4000, 2000),
|
||||
pya.Point(4000, 1000), pya.Point(2000, 1000), pya.Point(2000, 0) ] )
|
||||
ar = a.round_corners(100, 200, 8)
|
||||
self.assertEqual( str(ar), "(117,0;0,117;0,1883;117,2000;3883,2000;4000,1883;4000,1117;3883,1000;2059,1000;2000,941;2000,117;1883,0)" )
|
||||
ar = a.round_corners(200, 100, 32)
|
||||
self.assertEqual( str(ar), "(90,0;71,4;53,11;36,22;22,36;11,53;4,71;0,90;0,1910;4,1929;11,1947;22,1964;36,1978;53,1989;71,1996;90,2000;3910,2000;3929,1996;3947,1989;3964,1978;3978,1964;3989,1947;3996,1929;4000,1910;4000,1090;3996,1071;3989,1053;3978,1036;3964,1022;3947,1011;3929,1004;3910,1000;2180,1000;2142,992;2105,977;2073,955;2045,927;2023,895;2008,858;2000,820;2000,90;1996,71;1989,53;1978,36;1964,22;1947,11;1929,4;1910,0)" )
|
||||
|
||||
# Minkowsky sums
|
||||
p = pya.Polygon( [ pya.Point.new(0, -100), pya.Point.new(0, -50), pya.Point.new(-100, -75), pya.Point.new(0, 100), pya.Point.new(50, 50), pya.Point.new(100, 75), pya.Point.new(100, 0), pya.Point.new(100, -50) ] )
|
||||
self.assertEqual(str(p.minkowsky_sum(pya.Edge.new(pya.Point.new(10, 10), pya.Point.new(210, 110)), True)), "(10,-90;10,-40;-90,-65;10,110;210,210;260,160;310,185;310,60)")
|
||||
self.assertEqual(str(p.minkowsky_sum([pya.Point.new(10, 10), pya.Point.new(10, 310), pya.Point.new(510, 310), pya.Point.new(510, 10), pya.Point.new(10, 10) ], False)), "(10,-90;10,-65;-90,-65;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90/110,110;410,110;410,210;110,210)")
|
||||
self.assertEqual(str(p.minkowsky_sum([pya.Point.new(10, 10), pya.Point.new(10, 310), pya.Point.new(510, 310), pya.Point.new(510, 10), pya.Point.new(10, 10) ], True)), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)")
|
||||
self.assertEqual(str(p.minkowsky_sum(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 110)), True)), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)")
|
||||
self.assertEqual(str(p.minkowsky_sum(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 10)), True)), "(10,-90;10,-65;-90,-65;10,110;210,110;235,85;310,85;310,-40;210,-90)")
|
||||
self.assertEqual(str(p.minkowsky_sum(pya.Polygon.new(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 110))), True)), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)")
|
||||
|
||||
# Smoothing
|
||||
p = pya.Polygon( [ pya.Point.new(0, 0), pya.Point.new(10, 50), pya.Point.new(0, 100), pya.Point.new(200, 100), pya.Point.new(200, 0) ])
|
||||
self.assertEqual(str(p.smooth(5)), "(0,0;10,50;0,100;200,100;200,0)")
|
||||
self.assertEqual(str(p.smooth(15)), "(0,0;0,100;200,100;200,0)")
|
||||
|
||||
# Ellipse constructor
|
||||
p = pya.Polygon.ellipse( pya.Box(-10000, -20000, 30000, 40000), 200 )
|
||||
self.assertEqual(p.num_points(), 200)
|
||||
self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)")
|
||||
self.assertEqual(p.area(), 1884651158) # roughly box.area*PI/4
|
||||
|
||||
p = pya.Polygon.ellipse( pya.Box(-10000, -20000, 30000, 40000), 4 )
|
||||
self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
|
||||
|
||||
# Polygon parametrized edge iterator
|
||||
def test_2(self):
|
||||
|
||||
hull = [ pya.Point(0, 0), pya.Point(6000, 0),
|
||||
pya.Point(6000, 3000), pya.Point(0, 3000) ]
|
||||
hole1 = [ pya.Point(1000, 1000), pya.Point(2000, 1000),
|
||||
pya.Point(2000, 2000), pya.Point(1000, 2000) ]
|
||||
hole2 = [ pya.Point(3000, 1000), pya.Point(4000, 1000),
|
||||
pya.Point(4000, 2000), pya.Point(3000, 2000) ]
|
||||
poly = pya.Polygon(hull)
|
||||
poly.insert_hole(hole1)
|
||||
poly.insert_hole(hole2)
|
||||
|
||||
es = []
|
||||
for e in poly.each_edge():
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(0,0;0,3000)/(0,3000;6000,3000)/(6000,3000;6000,0)/(6000,0;0,0)/(1000,1000;2000,1000)/(2000,1000;2000,2000)/(2000,2000;1000,2000)/(1000,2000;1000,1000)/(3000,1000;4000,1000)/(4000,1000;4000,2000)/(4000,2000;3000,2000)/(3000,2000;3000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(0):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(0,0;0,3000)/(0,3000;6000,3000)/(6000,3000;6000,0)/(6000,0;0,0)" )
|
||||
es = []
|
||||
for e in poly.each_edge(1):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(1000,1000;2000,1000)/(2000,1000;2000,2000)/(2000,2000;1000,2000)/(1000,2000;1000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(2):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(3000,1000;4000,1000)/(4000,1000;4000,2000)/(4000,2000;3000,2000)/(3000,2000;3000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(3):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "" )
|
||||
|
||||
hull = [ pya.DPoint(0, 0), pya.DPoint(6000, 0),
|
||||
pya.DPoint(6000, 3000), pya.DPoint(0, 3000) ]
|
||||
hole1 = [ pya.DPoint(1000, 1000), pya.DPoint(2000, 1000),
|
||||
pya.DPoint(2000, 2000), pya.DPoint(1000, 2000) ]
|
||||
hole2 = [ pya.DPoint(3000, 1000), pya.DPoint(4000, 1000),
|
||||
pya.DPoint(4000, 2000), pya.DPoint(3000, 2000) ]
|
||||
poly = pya.DPolygon(hull)
|
||||
poly.insert_hole(hole1)
|
||||
poly.insert_hole(hole2)
|
||||
|
||||
es = []
|
||||
for e in poly.each_edge():
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(0,0;0,3000)/(0,3000;6000,3000)/(6000,3000;6000,0)/(6000,0;0,0)/(1000,1000;2000,1000)/(2000,1000;2000,2000)/(2000,2000;1000,2000)/(1000,2000;1000,1000)/(3000,1000;4000,1000)/(4000,1000;4000,2000)/(4000,2000;3000,2000)/(3000,2000;3000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(0):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(0,0;0,3000)/(0,3000;6000,3000)/(6000,3000;6000,0)/(6000,0;0,0)" )
|
||||
es = []
|
||||
for e in poly.each_edge(1):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(1000,1000;2000,1000)/(2000,1000;2000,2000)/(2000,2000;1000,2000)/(1000,2000;1000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(2):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "(3000,1000;4000,1000)/(4000,1000;4000,2000)/(4000,2000;3000,2000)/(3000,2000;3000,1000)" )
|
||||
es = []
|
||||
for e in poly.each_edge(3):
|
||||
es.append(str(e))
|
||||
self.assertEqual( "/".join(es), "" )
|
||||
|
||||
# raw mode polygons
|
||||
def test_2_Polygon(self):
|
||||
|
||||
pts = [ pya.Point(0, 0) ]
|
||||
p = pya.Polygon(pts, False)
|
||||
self.assertEqual(str(p), "()")
|
||||
|
||||
pts = [ pya.Point(0, 0) ]
|
||||
p = pya.Polygon(pts)
|
||||
self.assertEqual(str(p), "()")
|
||||
|
||||
pts = [ pya.Point(0, 0) ]
|
||||
p = pya.Polygon(pts, True)
|
||||
self.assertEqual(str(p), "(0,0)")
|
||||
|
||||
arr = []
|
||||
for e in p.each_edge():
|
||||
arr.append(str(e))
|
||||
self.assertEqual( arr, ["(0,0;0,0)"] )
|
||||
|
||||
p = pya.Polygon(pya.Box(0, 0, 100, 100))
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0)")
|
||||
p.insert_hole( [ pya.Point(0, 0), pya.Point(10, 0) ] )
|
||||
# TODO: this isn't nice (empty hole):
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/)")
|
||||
|
||||
p = pya.Polygon(pya.Box(0, 0, 100, 100))
|
||||
p.insert_hole( [ pya.Point(0, 0), pya.Point(10, 0) ], True )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
|
||||
p.assign_hole(0, [ pya.Point(0, 0), pya.Point(10, 0) ] )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/)")
|
||||
p.assign_hole(0, [ pya.Point(0, 0), pya.Point(10, 0) ], True )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
|
||||
|
||||
pts = [ pya.Point(0, 0), pya.Point(10, 0) ]
|
||||
p = pya.Polygon(pts, True)
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
# conversion of degenerated polygon to simple polygon is not supported currently:
|
||||
self.assertEqual(str(p.to_simple_polygon()), "()")
|
||||
self.assertEqual(str(pya.DPolygon(p)), "(0,0;10,0)")
|
||||
|
||||
p.hull = []
|
||||
self.assertEqual(str(p), "()")
|
||||
|
||||
p.hull = [ pya.Point(0, 0), pya.Point(10, 0) ]
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
|
||||
p.assign_hull([ pya.Point(0, 0), pya.Point(10, 0) ], False)
|
||||
self.assertEqual(str(p), "()")
|
||||
|
||||
p.assign_hull([ pya.Point(0, 0), pya.Point(10, 0) ], True)
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
|
||||
arr = []
|
||||
for e in p.each_edge():
|
||||
arr.append(str(e))
|
||||
self.assertEqual( arr, ["(0,0;10,0)", "(10,0;0,0)"] )
|
||||
|
||||
self.assertEqual(str(p.moved(1, 2)), "(1,2;11,2)")
|
||||
self.assertEqual(str(p.sized(2)), "(0,-2;0,2;10,2;10,-2)")
|
||||
self.assertEqual(str(p * 2), "(0,0;20,0)")
|
||||
self.assertEqual(str(p.transformed(pya.Trans(pya.Trans.R90))), "(0,0;0,10)")
|
||||
|
||||
pp = p.dup()
|
||||
pp.transform(pya.Trans(pya.Trans.R90))
|
||||
self.assertEqual(str(pp), "(0,0;0,10)")
|
||||
|
||||
p = pya.Polygon([ pya.Point(0, 0), pya.Point(0, 10) ], True)
|
||||
q = pya.Polygon([ pya.Point(1, 1), pya.Point(-9, 1) ], True)
|
||||
self.assertEqual(str(p.minkowsky_sum(q, False)), "(-9,1;-9,11;1,11;1,1)")
|
||||
|
||||
# raw mode polygons
|
||||
def test_2_DPolygon(self):
|
||||
|
||||
pts = [ pya.DPoint(0, 0) ]
|
||||
p = pya.DPolygon(pts, True)
|
||||
self.assertEqual(str(p), "(0,0)")
|
||||
|
||||
arr = []
|
||||
for e in p.each_edge():
|
||||
arr.append(str(e))
|
||||
self.assertEqual( arr, ["(0,0;0,0)"] )
|
||||
|
||||
p = pya.DPolygon(pya.DBox(0, 0, 100, 100))
|
||||
p.insert_hole( [ pya.DPoint(0, 0), pya.DPoint(10, 0) ], True )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
|
||||
p.assign_hole(0, [ pya.DPoint(0, 0), pya.DPoint(10, 0) ] )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
|
||||
p.assign_hole(0, [ pya.DPoint(0, 0), pya.DPoint(10, 0) ], True )
|
||||
self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
|
||||
|
||||
pts = [ pya.DPoint(0, 0), pya.DPoint(10, 0) ]
|
||||
p = pya.DPolygon(pts, True)
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
self.assertEqual(str(pya.Polygon(p)), "(0,0;10,0)")
|
||||
|
||||
p.hull = []
|
||||
self.assertEqual(str(p), "()")
|
||||
|
||||
p.hull = [ pya.DPoint(0, 0), pya.DPoint(10, 0) ]
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
|
||||
p.assign_hull([ pya.DPoint(0, 0), pya.DPoint(10, 0) ], True)
|
||||
self.assertEqual(str(p), "(0,0;10,0)")
|
||||
|
||||
arr = []
|
||||
for e in p.each_edge():
|
||||
arr.append(str(e))
|
||||
self.assertEqual( arr, ["(0,0;10,0)", "(10,0;0,0)"] )
|
||||
|
||||
self.assertEqual(str(p.moved(1, 2)), "(1,2;11,2)")
|
||||
self.assertEqual(str(p.sized(2)), "(0,-2;0,2;10,2;10,-2)")
|
||||
self.assertEqual(str(p * 2), "(0,0;20,0)")
|
||||
self.assertEqual(str(p.transformed(pya.DTrans(pya.DTrans.R90))), "(0,0;0,10)")
|
||||
|
||||
pp = p.dup()
|
||||
pp.transform(pya.DTrans(pya.DTrans.R90))
|
||||
self.assertEqual(str(pp), "(0,0;0,10)")
|
||||
|
||||
# is_convex
|
||||
def test_IsConvex(self):
|
||||
|
||||
self.assertEqual(pya.Polygon(pya.Box(0, 0, 10, 10)).is_convex(), True)
|
||||
|
||||
p = pya.Polygon.from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
self.assertEqual(p.is_convex(), False)
|
||||
|
||||
# polygon decomposition
|
||||
def test_PolygonDecompose(self):
|
||||
|
||||
p = pya.Polygon.from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
|
||||
self.assertEqual(str(p.decompose_convex()), "[(0,10;0,30;10,30;10,10), (0,30;0,40;30,40;30,30), (30,10;30,40;40,40;40,10), (0,0;0,10;40,10;40,0)]")
|
||||
self.assertEqual(str(p.decompose_convex(pya.Polygon.PO_any)), "[(0,10;0,30;10,30;10,10), (0,30;0,40;30,40;30,30), (30,10;30,40;40,40;40,10), (0,0;0,10;40,10;40,0)]")
|
||||
self.assertEqual(str(p.decompose_convex(pya.Polygon.PO_horizontal)), "[(0,10;0,30;10,30;10,10), (0,30;0,40;40,40;40,30), (30,10;30,30;40,30;40,10), (0,0;0,10;40,10;40,0)]")
|
||||
self.assertEqual(str(p.decompose_convex(pya.Polygon.PO_vertical)), "[(10,0;10,10;30,10;30,0), (0,0;0,40;10,40;10,0), (10,30;10,40;30,40;30,30), (30,0;30,40;40,40;40,0)]")
|
||||
self.assertEqual(str(p.decompose_convex(pya.Polygon.PO_htrapezoids)), "[(0,10;0,30;10,30;10,10), (0,30;0,40;30,40;30,30), (30,10;30,40;40,40;40,10), (0,0;0,10;40,10;40,0)]")
|
||||
self.assertEqual(str(p.decompose_convex(pya.Polygon.PO_vtrapezoids)), "[(10,0;10,10;30,10;30,0), (0,0;0,30;10,30;10,0), (0,30;0,40;30,40;30,30), (30,0;30,40;40,40;40,0)]")
|
||||
|
||||
self.assertEqual(str(p.decompose_trapezoids()), "[(0,0;0,10;40,10;40,0), (0,10;0,30;10,30;10,10), (30,10;30,30;40,30;40,10), (0,30;0,40;40,40;40,30)]")
|
||||
self.assertEqual(str(p.decompose_trapezoids(pya.Polygon.TD_simple)), "[(0,0;0,10;40,10;40,0), (0,10;0,30;10,30;10,10), (30,10;30,30;40,30;40,10), (0,30;0,40;40,40;40,30)]")
|
||||
self.assertEqual(str(p.decompose_trapezoids(pya.Polygon.TD_htrapezoids)), "[(0,10;0,30;10,30;10,10), (0,30;0,40;30,40;30,30), (30,10;30,40;40,40;40,10), (0,0;0,10;40,10;40,0)]")
|
||||
self.assertEqual(str(p.decompose_trapezoids(pya.Polygon.TD_vtrapezoids)), "[(10,0;10,10;30,10;30,0), (0,0;0,30;10,30;10,0), (0,30;0,40;30,40;30,30), (30,0;30,40;40,40;40,0)]")
|
||||
|
||||
# polygon decomposition
|
||||
def test_extractRad(self):
|
||||
|
||||
ex = pya.SimplePolygon().extract_rad()
|
||||
self.assertEqual(repr(ex), "[]")
|
||||
|
||||
sp = pya.SimplePolygon.from_s("(0,0;0,200000;300000,200000;300000,100000;100000,100000;100000,0)")
|
||||
|
||||
sp = sp.round_corners(10000, 5000, 200)
|
||||
ex = sp.extract_rad()
|
||||
|
||||
self.assertEqual(ex, [pya.SimplePolygon.from_s("(0,0;0,200000;300000,200000;300000,100000;100000,100000;100000,0)"), 10000.0, 5000.0, 200])
|
||||
|
||||
ex = pya.Polygon().extract_rad()
|
||||
self.assertEqual(ex, [])
|
||||
|
||||
sp = pya.Polygon.from_s("(0,0;0,300000;300000,300000;300000,0/100000,100000;200000,100000;200000,200000;100000,200000)")
|
||||
|
||||
sp = sp.round_corners(10000, 5000, 200)
|
||||
ex = sp.extract_rad()
|
||||
|
||||
self.assertEqual(ex, [pya.Polygon.from_s("(0,0;0,300000;300000,300000;300000,0/100000,100000;200000,100000;200000,200000;100000,200000)"), 10000.0, 5000.0, 200])
|
||||
|
||||
# double coords too ...
|
||||
|
||||
ex = pya.DSimplePolygon().extract_rad()
|
||||
self.assertEqual(ex, [])
|
||||
|
||||
sp = pya.DSimplePolygon.from_s("(0,0;0,200000;300000,200000;300000,100000;100000,100000;100000,0)")
|
||||
|
||||
sp = sp.round_corners(10000, 5000, 200)
|
||||
ex = sp.extract_rad()
|
||||
|
||||
# round to integers for better comparison
|
||||
|
||||
ex[0] = pya.SimplePolygon(ex[0])
|
||||
self.assertEqual(ex, [pya.SimplePolygon.from_s("(0,0;0,200000;300000,200000;300000,100000;100000,100000;100000,0)"), 10000.0, 5000.0, 200])
|
||||
|
||||
ex = pya.DPolygon().extract_rad()
|
||||
self.assertEqual(ex, [])
|
||||
|
||||
sp = pya.DPolygon.from_s("(0,0;0,300000;300000,300000;300000,0/100000,100000;200000,100000;200000,200000;100000,200000)")
|
||||
|
||||
sp = sp.round_corners(10000, 5000, 200)
|
||||
ex = sp.extract_rad()
|
||||
|
||||
# round to integers for better comparison
|
||||
ex[0] = pya.Polygon(ex[0])
|
||||
|
||||
self.assertEqual(ex, [pya.Polygon.from_s("(0,0;0,300000;300000,300000;300000,0/100000,100000;200000,100000;200000,200000;100000,200000)"), 10000.0, 5000.0, 200])
|
||||
|
||||
# fuzzy compare
|
||||
def test_FuzzyCompare(self):
|
||||
|
||||
p1 = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p2a = pya.DPolygon.from_s("(0.0000001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p2b = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10.0000001,10;30,10;30,30;10,30)")
|
||||
p3a = pya.DPolygon.from_s("(0.0001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p3b = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10.0001,10;30,10;30,30;10,30)")
|
||||
p4a = pya.DPolygon.from_s("(0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p4b = pya.DPolygon.from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p4c = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0)")
|
||||
p4d = pya.DPolygon.from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30/15,15;16,15;16,16;15,16)")
|
||||
|
||||
self.assertEqual(p1 == p2a, True)
|
||||
self.assertEqual(p1 == p2b, True)
|
||||
self.assertEqual(p1 == p3a, False)
|
||||
self.assertEqual(p1 == p3b, False)
|
||||
self.assertEqual(p1 == p4a, False)
|
||||
self.assertEqual(p1 == p4b, False)
|
||||
self.assertEqual(p1 == p4c, False)
|
||||
self.assertEqual(p1 == p4d, False)
|
||||
self.assertEqual(p1 < p2a, False)
|
||||
self.assertEqual(p1 < p2b, False)
|
||||
self.assertEqual(p1 < p3a, True)
|
||||
self.assertEqual(p1 < p3b, True)
|
||||
self.assertEqual(p1 < p4a, False)
|
||||
self.assertEqual(p1 < p4b, True)
|
||||
self.assertEqual(p1 < p4c, False)
|
||||
self.assertEqual(p1 < p4d, True)
|
||||
self.assertEqual(p4a < p4b, True)
|
||||
self.assertEqual(p4a < p4c, False)
|
||||
self.assertEqual(p4a < p4d, True)
|
||||
self.assertEqual(p4b < p4c, False)
|
||||
self.assertEqual(p4b < p4d, True)
|
||||
self.assertEqual(p4c < p4d, True)
|
||||
self.assertEqual(p2a < p1, False)
|
||||
self.assertEqual(p2b < p1, False)
|
||||
self.assertEqual(p3a < p1, False)
|
||||
self.assertEqual(p3b < p1, False)
|
||||
self.assertEqual(p4a < p1, True)
|
||||
self.assertEqual(p4b < p1, False)
|
||||
self.assertEqual(p4c < p1, True)
|
||||
self.assertEqual(p4d < p1, False)
|
||||
self.assertEqual(p4b < p4a, False)
|
||||
self.assertEqual(p4c < p4a, True)
|
||||
self.assertEqual(p4d < p4a, False)
|
||||
self.assertEqual(p4c < p4b, True)
|
||||
self.assertEqual(p4d < p4b, False)
|
||||
self.assertEqual(p4d < p4c, False)
|
||||
|
||||
# hash values
|
||||
def test_HashValues(self):
|
||||
|
||||
p1 = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p2a = pya.DPolygon.from_s("(0.0000001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p2b = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10.0000001,10;30,10;30,30;10,30)")
|
||||
p3a = pya.DPolygon.from_s("(0.0001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p3b = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0/10.0001,10;30,10;30,30;10,30)")
|
||||
p4a = pya.DPolygon.from_s("(0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p4b = pya.DPolygon.from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
|
||||
p4c = pya.DPolygon.from_s("(0,0;0,40;40,40;40,0)")
|
||||
p4d = pya.DPolygon.from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30/15,15;16,15;16,16;15,16)")
|
||||
|
||||
self.assertEqual(p1.hash() == p2a.hash(), True)
|
||||
self.assertEqual(p1.hash() == p2b.hash(), True)
|
||||
self.assertEqual(p1.hash() == p3a.hash(), False)
|
||||
self.assertEqual(p1.hash() == p3b.hash(), False)
|
||||
self.assertEqual(p1.hash() == p4a.hash(), False)
|
||||
self.assertEqual(p1.hash() == p4b.hash(), False)
|
||||
self.assertEqual(p1.hash() == p4c.hash(), False)
|
||||
self.assertEqual(p1.hash() == p4d.hash(), False)
|
||||
self.assertEqual(p4a.hash() == p4b.hash(), False)
|
||||
self.assertEqual(p4a.hash() == p4c.hash(), False)
|
||||
self.assertEqual(p4a.hash() == p4d.hash(), False)
|
||||
self.assertEqual(p4b.hash() == p4c.hash(), False)
|
||||
self.assertEqual(p4b.hash() == p4d.hash(), False)
|
||||
self.assertEqual(p4c.hash() == p4d.hash(), False)
|
||||
|
||||
if False:
|
||||
|
||||
# TODO: Currently, complex types are not allowed as hash keys:
|
||||
|
||||
h = { p1: "p1", p3a: "p3a", p3b: "p3b", p4a: "p4a", p4b: "p4b", p4c: "p4c", p4d: "p4d" }
|
||||
|
||||
self.assertEqual(h[p1], "p1")
|
||||
self.assertEqual(h[p2a], "p1")
|
||||
self.assertEqual(h[p2b], "p1")
|
||||
self.assertEqual(h[p3a], "p3a")
|
||||
self.assertEqual(h[p3b], "p3b")
|
||||
self.assertEqual(h[p4a], "p4a")
|
||||
self.assertEqual(h[p4b], "p4b")
|
||||
self.assertEqual(h[p4c], "p4c")
|
||||
self.assertEqual(h[p4d], "p4d")
|
||||
|
||||
# touches predicate
|
||||
def test_touches(self):
|
||||
|
||||
p1 = pya.Polygon(pya.Box(10, 20, 30, 40))
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.Box(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Box(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.Box(29, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Edge(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Edge(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.Edge(29, 20, 40, 50)), True)
|
||||
|
||||
p1 = pya.SimplePolygon(pya.Box(10, 20, 30, 40))
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.Polygon(pya.Box(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.Box(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Box(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.Box(29, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Edge(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.Edge(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.Edge(29, 20, 40, 50)), True)
|
||||
|
||||
p1 = pya.DPolygon(pya.DBox(10, 20, 30, 40))
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DBox(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DBox(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.DBox(29, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DEdge(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DEdge(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.DEdge(29, 20, 40, 50)), True)
|
||||
|
||||
p1 = pya.DSimplePolygon(pya.DBox(10, 20, 30, 40))
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(30, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(31, 20, 40, 50))), False)
|
||||
self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(29, 20, 40, 50))), True)
|
||||
self.assertEqual(p1.touches(pya.DBox(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DBox(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.DBox(29, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DEdge(30, 20, 40, 50)), True)
|
||||
self.assertEqual(p1.touches(pya.DEdge(31, 20, 40, 50)), False)
|
||||
self.assertEqual(p1.touches(pya.DEdge(29, 20, 40, 50)), True)
|
||||
|
||||
def test_selfRef(self):
|
||||
|
||||
# p1 is a reference to the new'd object:
|
||||
p1 = pya.Polygon(pya.Box(10, 20, 30, 40)).move(10, 20)
|
||||
self.assertEqual(str(p1), "(20,40;20,60;40,60;40,40)")
|
||||
|
||||
pp = pya.Polygon(pya.Box(10, 20, 30, 40))
|
||||
p1 = pp.move(10, 20)
|
||||
self.assertEqual(str(p1), "(20,40;20,60;40,60;40,40)")
|
||||
self.assertEqual(str(pp), "(20,40;20,60;40,60;40,40)")
|
||||
pp.move(1, 2)
|
||||
|
||||
# p1 and pp are the same object
|
||||
self.assertEqual(str(p1), "(21,42;21,62;41,62;41,42)")
|
||||
self.assertEqual(str(pp), "(21,42;21,62;41,62;41,42)")
|
||||
|
||||
# run unit tests
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(DBPolygonTests)
|
||||
|
||||
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
|
||||
sys.exit(1)
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+591
@@ -0,0 +1,591 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import pya
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
class DBTransTests(unittest.TestCase):
|
||||
|
||||
# Transformation basics
|
||||
def test_1_DTrans(self):
|
||||
|
||||
a = pya.DTrans()
|
||||
b = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ))
|
||||
c = pya.DTrans( 3, True, pya.DPoint( 17, 5 ))
|
||||
d = pya.DTrans( pya.DPoint( 17, 5 ))
|
||||
e = pya.DTrans( pya.DTrans.M135 )
|
||||
e2 = pya.DTrans.from_itrans( pya.Trans.M135 )
|
||||
f = pya.DTrans( pya.Trans( pya.Trans.M135, pya.Point( 17, 5 )) )
|
||||
|
||||
self.assertEqual( str(a), "r0 0,0" )
|
||||
self.assertEqual( str(pya.DTrans.from_s(str(a))), str(a) )
|
||||
self.assertEqual( str(b), "m135 17,5" )
|
||||
self.assertEqual( str(c), "m135 17,5" )
|
||||
self.assertEqual( str(d), "r0 17,5" )
|
||||
self.assertEqual( str(e), "m135 0,0" )
|
||||
self.assertEqual( str(e2), "m135 0,0" )
|
||||
self.assertEqual( str(f), "m135 17,5" )
|
||||
self.assertEqual( str(pya.DTrans.from_s(str(f))), str(f) )
|
||||
|
||||
self.assertEqual( str(b.trans( pya.DPoint( 1, 0 ))), "17,4" )
|
||||
|
||||
self.assertEqual( a == b, False )
|
||||
self.assertEqual( a == a, True )
|
||||
self.assertEqual( a != b, True )
|
||||
self.assertEqual( a != a, False )
|
||||
self.assertEqual( (d * e) == b, True )
|
||||
self.assertEqual( (e * d) == b, False )
|
||||
|
||||
i = c.inverted()
|
||||
|
||||
self.assertEqual( str(i), "m135 5,17" )
|
||||
self.assertEqual( (i * b) == a, True )
|
||||
self.assertEqual( (b * i) == a, True )
|
||||
|
||||
c = pya.DTrans( 3, True, pya.DPoint( 17, 5 ))
|
||||
self.assertEqual( str(c), "m135 17,5" )
|
||||
c.disp = pya.DPoint(1, 7)
|
||||
self.assertEqual( str(c), "m135 1,7" )
|
||||
c.angle = 1
|
||||
self.assertEqual( str(c), "m45 1,7" )
|
||||
c.rot = 3
|
||||
self.assertEqual( str(c), "r270 1,7" )
|
||||
c.mirror = True
|
||||
self.assertEqual( str(c), "m135 1,7" )
|
||||
|
||||
self.assertEqual( str(pya.Trans(pya.Trans.R180, 5,-7)), "r180 5,-7" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans.R180, pya.Point(5,-7))), "r180 5,-7" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans.R180, pya.Vector(5,-7))), "r180 5,-7" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans.R180, pya.DVector(5,-7))), "r180 5,-7" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans.R180)), "r180 0,0" )
|
||||
|
||||
self.assertEqual( str(e.trans( pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(( e * pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(e.trans( pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(( e * pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(e.trans( pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(( e * pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(e.trans( pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(( e * pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(e.trans( pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
self.assertEqual( str(( e * pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
|
||||
# Constructor variations
|
||||
self.assertEqual( str(pya.Trans()), "r0 0,0" )
|
||||
self.assertEqual( str(pya.Trans(1)), "r90 0,0" )
|
||||
self.assertEqual( str(pya.Trans(2, True)), "m90 0,0" )
|
||||
self.assertEqual( str(pya.Trans(2, True, pya.Vector(100, 200))), "m90 100,200" )
|
||||
self.assertEqual( str(pya.Trans(2, True, 100, 200)), "m90 100,200" )
|
||||
self.assertEqual( str(pya.Trans(pya.Vector(100, 200))), "r0 100,200" )
|
||||
self.assertEqual( str(pya.Trans(100, 200)), "r0 100,200" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans(100, 200), 10, 20)), "r0 110,220" )
|
||||
self.assertEqual( str(pya.Trans(pya.Trans(100, 200), pya.Vector(10, 20))), "r0 110,220" )
|
||||
|
||||
self.assertEqual( str(pya.DTrans()), "r0 0,0" )
|
||||
self.assertEqual( str(pya.DTrans(1)), "r90 0,0" )
|
||||
self.assertEqual( str(pya.DTrans(2, True)), "m90 0,0" )
|
||||
self.assertEqual( str(pya.DTrans(2, True, pya.DVector(0.1, 0.2))), "m90 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DTrans(2, True, 0.1, 0.2)), "m90 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DTrans(pya.DVector(0.1, 0.2))), "r0 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DTrans(0.1, 0.2)), "r0 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DTrans(pya.DTrans(0.1, 0.2), 0.01, 0.02)), "r0 0.11,0.22" )
|
||||
self.assertEqual( str(pya.DTrans(pya.DTrans(0.1, 0.2), pya.DVector(0.01, 0.02))), "r0 0.11,0.22" )
|
||||
|
||||
# Magnification basics
|
||||
def test_2_DTrans(self):
|
||||
|
||||
a = pya.DTrans()
|
||||
b = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ))
|
||||
ma = pya.DCplxTrans( a, 0.5 )
|
||||
mb = pya.DCplxTrans( b, 2.0 )
|
||||
u = pya.DCplxTrans( a )
|
||||
|
||||
self.assertEqual( str(ma), "r0 *0.5 0,0" )
|
||||
self.assertEqual( str(mb), "m135 *2 17,5" )
|
||||
|
||||
self.assertEqual( ma == mb, False )
|
||||
self.assertEqual( ma == ma, True )
|
||||
self.assertEqual( ma != mb, True )
|
||||
self.assertEqual( ma != ma, False )
|
||||
|
||||
i = mb.inverted()
|
||||
|
||||
self.assertEqual( str(i), "m135 *0.5 2.5,8.5" )
|
||||
self.assertEqual( str(pya.DCplxTrans.from_s(str(i))), str(i) )
|
||||
self.assertEqual( i * mb == u, True )
|
||||
self.assertEqual( mb * i == u, True )
|
||||
|
||||
self.assertEqual( str(mb.trans( pya.DPoint( 1, 0 ))), "17,3" )
|
||||
self.assertEqual( str(mb.ctrans(2)), "4.0" )
|
||||
self.assertEqual( str(i.ctrans(2)), "1.0" )
|
||||
|
||||
# Complex transformation specials
|
||||
def test_3_DTrans(self):
|
||||
|
||||
c = pya.DCplxTrans( 5.0, -7.0 )
|
||||
self.assertEqual( str(c), "r0 *1 5,-7" )
|
||||
|
||||
c = pya.DCplxTrans( pya.DCplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), True )
|
||||
self.assertEqual( c.is_mag(), False )
|
||||
self.assertEqual( c.is_mirror(), True )
|
||||
self.assertEqual( c.rot(), pya.DCplxTrans.M135.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "m135 0,0" )
|
||||
self.assertEqual( c.angle, 270 )
|
||||
|
||||
self.assertEqual( str(c.trans( pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(( c * pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(c.trans( pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(( c * pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(c.trans( pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(( c * pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(c.trans( pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(( c * pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(c.trans( pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
self.assertEqual( str(( c * pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
|
||||
c = pya.DCplxTrans.from_itrans( pya.CplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
|
||||
c = pya.DCplxTrans( 1.5 )
|
||||
self.assertEqual( str(c), "r0 *1.5 0,0" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), True )
|
||||
self.assertEqual( c.is_mag(), True )
|
||||
self.assertEqual( c.is_mirror(), False )
|
||||
self.assertEqual( c.rot(), pya.DCplxTrans.R0.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "r0 0,0" )
|
||||
self.assertEqual( c.angle, 0 )
|
||||
|
||||
c = pya.DCplxTrans( 0.75, 45, True, 2.5, -12.5 )
|
||||
self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" )
|
||||
c = pya.DCplxTrans( 0.75, 45, True, pya.DPoint( 2.5, -12.5 ) )
|
||||
self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), False )
|
||||
self.assertEqual( c.is_mag(), True )
|
||||
self.assertEqual( c.rot(), pya.DCplxTrans.M0.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "m0 2.5,-12.5" )
|
||||
self.assertEqual( c.angle, 45 )
|
||||
|
||||
self.assertEqual( str(c.ctrans( 5 )), "3.75" )
|
||||
self.assertEqual( str(c.trans( pya.DPoint( 12, 16 ) )), "17.3492424049,-14.6213203436" )
|
||||
|
||||
self.assertEqual( str(pya.DCplxTrans()), "r0 *1 0,0" )
|
||||
self.assertEqual( pya.DCplxTrans().is_unity(), True )
|
||||
self.assertEqual( (c * c.inverted()).is_unity(), True )
|
||||
|
||||
c.mirror = False
|
||||
self.assertEqual( str(c), "r45 *0.75 2.5,-12.5" )
|
||||
c.mag = 1.5
|
||||
self.assertEqual( str(c), "r45 *1.5 2.5,-12.5" )
|
||||
c.disp = pya.DPoint( -1.0, 5.5 )
|
||||
self.assertEqual( str(c), "r45 *1.5 -1,5.5" )
|
||||
self.assertEqual( c.mag, 1.5 )
|
||||
c.angle = 60
|
||||
self.assertEqual( str(c), "r60 *1.5 -1,5.5" )
|
||||
self.assertEqual( ("%g" % c.angle), "60" )
|
||||
|
||||
# Constructor variations
|
||||
self.assertEqual( str(pya.ICplxTrans()), "r0 *1 0,0" )
|
||||
self.assertEqual( str(pya.ICplxTrans(1.5)), "r0 *1.5 0,0" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.Trans(1, False, 10, 20), 1.5)), "r90 *1.5 10,20" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.Trans(1, False, 10, 20))), "r90 *1 10,20" )
|
||||
self.assertEqual( str(pya.ICplxTrans(1.5, 80, True, pya.Vector(100, 200))), "m40 *1.5 100,200" )
|
||||
self.assertEqual( str(pya.ICplxTrans(1.5, 80, True, 100, 200)), "m40 *1.5 100,200" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.Vector(100, 200))), "r0 *1 100,200" )
|
||||
self.assertEqual( str(pya.ICplxTrans(100, 200)), "r0 *1 100,200" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans(100, 200))), "r0 *1 100,200" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5)), "r0 *1.5 150,300" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, pya.Vector(10, 20))), "r0 *1.5 160,320" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, 10, 20)), "r0 *1.5 160,320" )
|
||||
|
||||
self.assertEqual( str(pya.DCplxTrans()), "r0 *1 0,0" )
|
||||
self.assertEqual( str(pya.DCplxTrans(1.5)), "r0 *1.5 0,0" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02), 1.5)), "r90 *1.5 0.01,0.02" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02))), "r90 *1 0.01,0.02" )
|
||||
self.assertEqual( str(pya.DCplxTrans(1.5, 80, True, pya.DVector(0.1, 0.2))), "m40 *1.5 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DCplxTrans(1.5, 80, True, 0.1, 0.2)), "m40 *1.5 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DVector(0.1, 0.2))), "r0 *1 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DCplxTrans(0.1, 0.2)), "r0 *1 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2))), "r0 *1 0.1,0.2" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5)), "r0 *1.5 0.15,0.3" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, pya.DVector(0.01, 0.02))), "r0 *1.5 0.16,0.32" )
|
||||
self.assertEqual( str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, 0.01, 0.02)), "r0 *1.5 0.16,0.32" )
|
||||
|
||||
# Transformation basics
|
||||
def test_1_Trans(self):
|
||||
|
||||
a = pya.Trans()
|
||||
b = pya.Trans( pya.Trans.M135, pya.Point( 17, 5 ))
|
||||
c = pya.Trans( 3, True, pya.Point( 17, 5 ))
|
||||
d = pya.Trans( pya.Point( 17, 5 ))
|
||||
e = pya.Trans( pya.Trans.M135 )
|
||||
e2 = pya.Trans.from_dtrans( pya.DTrans.M135 )
|
||||
f = pya.Trans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 )) )
|
||||
|
||||
self.assertEqual( str(a), "r0 0,0" )
|
||||
self.assertEqual( str(pya.Trans.from_s(str(a))), str(a) )
|
||||
self.assertEqual( str(b), "m135 17,5" )
|
||||
self.assertEqual( str(c), "m135 17,5" )
|
||||
self.assertEqual( str(d), "r0 17,5" )
|
||||
self.assertEqual( str(e), "m135 0,0" )
|
||||
self.assertEqual( str(e2), "m135 0,0" )
|
||||
self.assertEqual( str(f), "m135 17,5" )
|
||||
self.assertEqual( str(pya.Trans.from_s(str(f))), str(f) )
|
||||
|
||||
self.assertEqual( str(b.trans( pya.Point( 1, 0 ))), "17,4" )
|
||||
|
||||
self.assertEqual( a == b, False )
|
||||
self.assertEqual( a == a, True )
|
||||
self.assertEqual( a != b, True )
|
||||
self.assertEqual( a != a, False )
|
||||
self.assertEqual( (d * e) == b, True )
|
||||
self.assertEqual( (e * d) == b, False )
|
||||
|
||||
i = c.inverted()
|
||||
|
||||
self.assertEqual( str(i), "m135 5,17" )
|
||||
self.assertEqual( (i * b) == a, True )
|
||||
self.assertEqual( (b * i) == a, True )
|
||||
|
||||
c = pya.Trans( 3, True, pya.Point( 17, 5 ))
|
||||
self.assertEqual( str(c), "m135 17,5" )
|
||||
c.disp = pya.Point(1, 7)
|
||||
self.assertEqual( str(c), "m135 1,7" )
|
||||
c.angle = 1
|
||||
self.assertEqual( str(c), "m45 1,7" )
|
||||
c.rot = 3
|
||||
self.assertEqual( str(c), "r270 1,7" )
|
||||
c.mirror = True
|
||||
self.assertEqual( str(c), "m135 1,7" )
|
||||
|
||||
self.assertEqual( str(e.trans( pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(( e * pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" )
|
||||
self.assertEqual( str(e.trans( pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(( e * pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
|
||||
self.assertEqual( str(e.trans( pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(( e * pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
|
||||
self.assertEqual( str(e.trans( pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(( e * pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
|
||||
self.assertEqual( str(e.trans( pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
self.assertEqual( str(( e * pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
|
||||
# Complex transformation basics
|
||||
def test_2_Trans(self):
|
||||
|
||||
a = pya.Trans()
|
||||
b = pya.Trans( pya.Trans.M135, pya.Point( 17, 5 ))
|
||||
ma = pya.CplxTrans( a, 0.5 )
|
||||
mb = pya.CplxTrans( b, 2.0 )
|
||||
u = pya.CplxTrans( a )
|
||||
|
||||
self.assertEqual( str(ma), "r0 *0.5 0,0" )
|
||||
self.assertEqual( str(mb), "m135 *2 17,5" )
|
||||
|
||||
self.assertEqual( ma == mb, False )
|
||||
self.assertEqual( ma == ma, True )
|
||||
self.assertEqual( ma != mb, True )
|
||||
self.assertEqual( ma != ma, False )
|
||||
|
||||
self.assertEqual( str(mb.inverted()), "m135 *0.5 2.5,8.5" )
|
||||
|
||||
i = mb.dup()
|
||||
i.invert()
|
||||
|
||||
self.assertEqual( str(i), "m135 *0.5 2.5,8.5" )
|
||||
self.assertEqual( i * mb == u, True )
|
||||
self.assertEqual( mb * i == u, True )
|
||||
|
||||
self.assertEqual( str(mb.trans( pya.Point( 1, 0 ))), "17,3" )
|
||||
self.assertEqual( str(mb.ctrans(2)), "4.0" )
|
||||
self.assertEqual( str(i.ctrans(2)), "1.0" )
|
||||
|
||||
# Complex transformation specials
|
||||
def test_3_Trans(self):
|
||||
|
||||
c = pya.CplxTrans( 5, -7 )
|
||||
self.assertEqual( str(c), "r0 *1 5,-7" )
|
||||
self.assertEqual( str(pya.CplxTrans.from_s(str(c))), str(c) )
|
||||
|
||||
c = pya.CplxTrans( pya.CplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), True )
|
||||
self.assertEqual( c.is_mag(), False )
|
||||
self.assertEqual( c.is_mirror(), True )
|
||||
self.assertEqual( c.rot(), pya.CplxTrans.M135.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "m135 0,0" )
|
||||
self.assertEqual( c.angle, 270 )
|
||||
|
||||
c = pya.CplxTrans.from_dtrans( pya.DCplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
|
||||
c = pya.CplxTrans( 1.5 )
|
||||
self.assertEqual( str(c), "r0 *1.5 0,0" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), True )
|
||||
self.assertEqual( c.is_mag(), True )
|
||||
self.assertEqual( c.is_mirror(), False )
|
||||
self.assertEqual( c.rot(), pya.CplxTrans.R0.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "r0 0,0" )
|
||||
self.assertEqual( c.angle, 0 )
|
||||
|
||||
c = pya.CplxTrans( 0.75, 45, True, 2.5, -12.5 )
|
||||
self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" )
|
||||
self.assertEqual( str(pya.CplxTrans.from_s(str(c))), str(c) )
|
||||
c = pya.CplxTrans( 0.75, 45, True, pya.DPoint( 2.5, -12.5 ) )
|
||||
self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" )
|
||||
self.assertEqual( c.is_unity(), False )
|
||||
self.assertEqual( c.is_ortho(), False )
|
||||
self.assertEqual( c.is_mag(), True )
|
||||
self.assertEqual( c.rot(), pya.CplxTrans.M0.rot() )
|
||||
self.assertEqual( str(c.s_trans()), "m0 3,-13" )
|
||||
self.assertEqual( c.angle, 45 )
|
||||
|
||||
self.assertEqual( str(c.ctrans( 5 )), "3.75" )
|
||||
self.assertEqual( str(c.trans( pya.Point( 12, 16 ) )), "17.3492424049,-14.6213203436" )
|
||||
|
||||
self.assertEqual( str(pya.CplxTrans()), "r0 *1 0,0" )
|
||||
self.assertEqual( pya.CplxTrans().is_unity(), True )
|
||||
self.assertEqual( (c.inverted() * c).is_unity(), True )
|
||||
|
||||
c.mirror = False
|
||||
self.assertEqual( str(c), "r45 *0.75 2.5,-12.5" )
|
||||
c.mag = 1.5
|
||||
self.assertEqual( str(c), "r45 *1.5 2.5,-12.5" )
|
||||
c.disp = pya.DPoint( -1.0, 5.5 )
|
||||
self.assertEqual( str(c), "r45 *1.5 -1,5.5" )
|
||||
self.assertEqual( c.mag, 1.5 )
|
||||
c.angle = 60
|
||||
self.assertEqual( str(c), "r60 *1.5 -1,5.5" )
|
||||
self.assertEqual( ("%g" % c.angle), "60" )
|
||||
|
||||
# Complex transformation types
|
||||
def test_4_Trans(self):
|
||||
|
||||
a = pya.Trans()
|
||||
m = pya.CplxTrans( a, 1.1 )
|
||||
da = pya.DTrans()
|
||||
dm = pya.DCplxTrans( da, 1.1 )
|
||||
|
||||
self.assertEqual( str(m), "r0 *1.1 0,0" )
|
||||
self.assertEqual( str(pya.DCplxTrans.from_s(str(m))), str(m) )
|
||||
self.assertEqual( str(m.trans( pya.Point( 5, -7 ))), "5.5,-7.7" )
|
||||
|
||||
im = pya.ICplxTrans( a, 0.5 )
|
||||
im_old = im.dup()
|
||||
|
||||
self.assertEqual( str(im), "r0 *0.5 0,0" )
|
||||
self.assertEqual( str(pya.ICplxTrans.from_s(str(im))), str(im) )
|
||||
self.assertEqual( str(im.trans( pya.Point( 5, -7 ))), "3,-4" )
|
||||
|
||||
im = pya.ICplxTrans(m)
|
||||
self.assertEqual( str(im), "r0 *1.1 0,0" )
|
||||
self.assertEqual( str(im.trans( pya.Point( 5, -7 ))), "6,-8" )
|
||||
|
||||
im = pya.ICplxTrans(dm)
|
||||
self.assertEqual( str(im), "r0 *1.1 0,0" )
|
||||
self.assertEqual( str(im.trans( pya.Point( 5, -7 ))), "6,-8" )
|
||||
|
||||
im.assign(im_old)
|
||||
self.assertEqual( str(im), "r0 *0.5 0,0" )
|
||||
self.assertEqual( str(im.trans( pya.Point( 5, -7 ))), "3,-4" )
|
||||
|
||||
self.assertEqual( str(pya.ICplxTrans(5,-7)), "r0 *1 5,-7" )
|
||||
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, 5,-7)), "r180 *1.5 5,-7" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Point(5,-7))), "r180 *1.5 5,-7" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Vector(5,-7))), "r180 *1.5 5,-7" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.DVector(5,-7))), "r180 *1.5 5,-7" )
|
||||
self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5)), "r180 *1.5 0,0" )
|
||||
|
||||
c = pya.ICplxTrans.from_dtrans( pya.DCplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
c = pya.ICplxTrans.from_trans( pya.CplxTrans.M135 )
|
||||
self.assertEqual( str(c), "m135 *1 0,0" )
|
||||
|
||||
# Fuzzy compare
|
||||
def test_5_Trans_FuzzyCompare(self):
|
||||
|
||||
t1 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ))
|
||||
t2 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-7, 5 ))
|
||||
t3 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-4, 5 ))
|
||||
t4a = pya.DTrans( pya.DTrans.M135, pya.DPoint( 18, 5 ))
|
||||
t4b = pya.DTrans( pya.DTrans.R90, pya.DPoint( 18, 5 ))
|
||||
|
||||
self.assertEqual(t1 == t2, True)
|
||||
self.assertEqual(t1 != t2, False)
|
||||
self.assertEqual(t1 < t2, False)
|
||||
self.assertEqual(t2 < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t3, False)
|
||||
self.assertEqual(t1 != t3, True)
|
||||
self.assertEqual(t1 < t3, True)
|
||||
self.assertEqual(t3 < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t4a, False)
|
||||
self.assertEqual(t1 != t4a, True)
|
||||
self.assertEqual(t1 < t4a, True)
|
||||
self.assertEqual(t4a < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t4b, False)
|
||||
self.assertEqual(t1 != t4b, True)
|
||||
self.assertEqual(t1 < t4b, False)
|
||||
self.assertEqual(t4b < t1, True)
|
||||
|
||||
# Complex trans fuzzy compare
|
||||
def test_5_CplxTrans_FuzzyCompare(self):
|
||||
|
||||
t1 = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t2a = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-7, 5 ) ), 1.0)
|
||||
t2b = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0 + 1e-11)
|
||||
t2c = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t2c.angle = t2c.angle + 1e-11
|
||||
t3a = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-4, 5 ) ), 1.0)
|
||||
t3b = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0 + 1e-4)
|
||||
t3c = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t3c.angle = t3c.angle + 1e-4
|
||||
t4 = pya.DCplxTrans( pya.DTrans( pya.DTrans.R90, pya.DPoint( 18, 5 ) ), 1.0)
|
||||
|
||||
self.assertEqual(t1 == t2a, True)
|
||||
self.assertEqual(t1 != t2a, False)
|
||||
self.assertEqual(t1 < t2a, False)
|
||||
self.assertEqual(t2a < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t2b, True)
|
||||
self.assertEqual(t1 != t2b, False)
|
||||
self.assertEqual(t1 < t2b, False)
|
||||
self.assertEqual(t2b < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t2c, True)
|
||||
self.assertEqual(t1 != t2c, False)
|
||||
self.assertEqual(t1 < t2c, False)
|
||||
self.assertEqual(t2c < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t3a, False)
|
||||
self.assertEqual(t1 != t3a, True)
|
||||
self.assertEqual(t1 < t3a, True)
|
||||
self.assertEqual(t3a < t1, False)
|
||||
|
||||
self.assertEqual(t1 == t3b, False)
|
||||
self.assertEqual(t1 != t3b, True)
|
||||
self.assertEqual(t1 < t3b, False)
|
||||
self.assertEqual(t3b < t1, True)
|
||||
|
||||
self.assertEqual(t1 == t3c, False)
|
||||
self.assertEqual(t1 != t3c, True)
|
||||
self.assertEqual(t1 < t3c, True)
|
||||
self.assertEqual(t3c < t1, False)
|
||||
|
||||
self.assertEqual(t3a == t3b, False)
|
||||
self.assertEqual(t3a != t3b, True)
|
||||
self.assertEqual(t3a < t3b, False)
|
||||
self.assertEqual(t3b < t3a, True)
|
||||
|
||||
self.assertEqual(t3a == t3c, False)
|
||||
self.assertEqual(t3a != t3c, True)
|
||||
self.assertEqual(t3a < t3c, False)
|
||||
self.assertEqual(t3c < t3a, True)
|
||||
|
||||
self.assertEqual(t3b == t3c, False)
|
||||
self.assertEqual(t3b != t3c, True)
|
||||
self.assertEqual(t3b < t3c, True)
|
||||
self.assertEqual(t3c < t3b, False)
|
||||
|
||||
self.assertEqual(t1 == t4, False)
|
||||
self.assertEqual(t1 != t4, True)
|
||||
self.assertEqual(t1 < t4, True)
|
||||
self.assertEqual(t4 < t1, False)
|
||||
|
||||
# Hash values
|
||||
def test_5_Trans_Hash(self):
|
||||
|
||||
t1 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ))
|
||||
t2 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-7, 5 ))
|
||||
t3 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-4, 5 ))
|
||||
t4a = pya.DTrans( pya.DTrans.M135, pya.DPoint( 18, 5 ))
|
||||
t4b = pya.DTrans( pya.DTrans.R90, pya.DPoint( 18, 5 ))
|
||||
|
||||
self.assertEqual(t1.hash() == t2.hash(), True)
|
||||
self.assertEqual(t1.hash() == t3.hash(), False)
|
||||
self.assertEqual(t1.hash() == t4a.hash(), False)
|
||||
self.assertEqual(t1.hash() == t4b.hash(), False)
|
||||
|
||||
# Transformations can't be used as hash keys currently
|
||||
if False:
|
||||
|
||||
h = { t1: "t1", t3: "t3", t4a: "t4a", t4b: "t4b" }
|
||||
|
||||
self.assertEqual(h[t1], "t1")
|
||||
self.assertEqual(h[t2], "t1")
|
||||
self.assertEqual(h[t3], "t3")
|
||||
self.assertEqual(h[t4a], "t4a")
|
||||
self.assertEqual(h[t4b], "t4b")
|
||||
|
||||
# Complex trans hash values
|
||||
def test_5_CplxTrans_Hash(self):
|
||||
|
||||
t1 = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t2a = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-7, 5 ) ), 1.0)
|
||||
t2b = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0 + 1e-11)
|
||||
t2c = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t2c.angle = t2c.angle + 1e-11
|
||||
t3a = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17 + 1e-4, 5 ) ), 1.0)
|
||||
t3b = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0 + 1e-4)
|
||||
t3c = pya.DCplxTrans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 ) ), 1.0)
|
||||
t3c.angle = t3c.angle + 1e-4
|
||||
t4 = pya.DCplxTrans( pya.DTrans( pya.DTrans.R90, pya.DPoint( 18, 5 ) ), 1.0)
|
||||
|
||||
self.assertEqual(t1.hash() == t2a.hash(), True)
|
||||
self.assertEqual(t1.hash() == t2b.hash(), True)
|
||||
self.assertEqual(t1.hash() == t2c.hash(), True)
|
||||
self.assertEqual(t1.hash() == t3a.hash(), False)
|
||||
self.assertEqual(t1.hash() == t3b.hash(), False)
|
||||
self.assertEqual(t1.hash() == t3c.hash(), False)
|
||||
self.assertEqual(t3a.hash() == t3b.hash(), False)
|
||||
self.assertEqual(t3a.hash() == t3c.hash(), False)
|
||||
self.assertEqual(t3b.hash() == t3c.hash(), False)
|
||||
self.assertEqual(t1.hash() == t4.hash(), False)
|
||||
|
||||
# Transformations can't be used as hash keys currently
|
||||
if False:
|
||||
|
||||
h = { t1: "t1", t3a: "t3a", t3b: "t3b", t3c: "t3c", t4: "t4" }
|
||||
|
||||
self.assertEqual(h[t1], "t1")
|
||||
self.assertEqual(h[t2a], "t1")
|
||||
self.assertEqual(h[t2b], "t1")
|
||||
self.assertEqual(h[t2c], "t1")
|
||||
self.assertEqual(h[t3a], "t3a")
|
||||
self.assertEqual(h[t3b], "t3b")
|
||||
self.assertEqual(h[t3c], "t3c")
|
||||
self.assertEqual(h[t4], "t4")
|
||||
|
||||
|
||||
# run unit tests
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(DBTransTests)
|
||||
|
||||
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
|
||||
sys.exit(1)
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+49
-46
@@ -1,51 +1,8 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# extend A
|
||||
class RBA::A
|
||||
|
||||
def initialize
|
||||
@offset = nil
|
||||
end
|
||||
def s( o )
|
||||
@offset = o
|
||||
end
|
||||
def g
|
||||
return @offset
|
||||
end
|
||||
def m
|
||||
return @offset+a1
|
||||
end
|
||||
def call_a10_prot(f)
|
||||
a10_prot(f)
|
||||
end
|
||||
def inspect
|
||||
if @offset
|
||||
@offset.to_s
|
||||
else
|
||||
"a1=" + self.a1.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@offset
|
||||
|
||||
end
|
||||
|
||||
class XEdge < RBA::Edge
|
||||
def initialize
|
||||
super(RBA::Point.new(1,2), RBA::Point.new(3,4))
|
||||
end
|
||||
end
|
||||
|
||||
class RBA::E
|
||||
def m
|
||||
@m
|
||||
end
|
||||
def m=(x)
|
||||
@m = x
|
||||
end
|
||||
@m = nil
|
||||
end
|
||||
# NOTE: we need to do a "require" here since basic_testcore_defs.rb is not
|
||||
# safe in multiple inclusions
|
||||
require File.expand_path('../basic_testcore_defs', __FILE__)
|
||||
|
||||
class Basic_TestClass < TestBase
|
||||
|
||||
@@ -63,6 +20,11 @@ class Basic_TestClass < TestBase
|
||||
a = RBA::A.new_a(100)
|
||||
assert_equal( RBA::A::a0, ac0 + 1 )
|
||||
|
||||
a = RBA::A.new
|
||||
assert_equal(a.a1, 17)
|
||||
a.assign(RBA::A.new(110))
|
||||
assert_equal(a.a1, 110)
|
||||
|
||||
a = nil
|
||||
GC.start
|
||||
assert_equal( RBA::A::a0, ac0 )
|
||||
@@ -2601,4 +2563,45 @@ class Basic_TestClass < TestBase
|
||||
|
||||
end
|
||||
|
||||
def test_73
|
||||
|
||||
begin
|
||||
|
||||
poly = RBA::Polygon::new(RBA::Box::new(0, 0, 100, 100))
|
||||
|
||||
# passing exceptions over iterators is critical because it involves
|
||||
# a Ruby/C++ and C++/Ruby transition
|
||||
poly.each_edge do |e|
|
||||
raise MyException::new("some exception")
|
||||
end
|
||||
|
||||
rescue => ex
|
||||
assert_equal(ex.class.to_s, "MyException")
|
||||
assert_equal(ex.to_s, "some exception")
|
||||
end
|
||||
|
||||
begin
|
||||
raise MyException::new("another exception")
|
||||
rescue => ex
|
||||
assert_equal(ex.class.to_s, "MyException")
|
||||
assert_equal(ex.to_s, "another exception")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Custom factory implemented in Ruby
|
||||
def test_80
|
||||
|
||||
gc = RBA::GObject.g_inst_count
|
||||
gf = RBAGFactory::new
|
||||
go = RBA::GFactory.create_f(gf, 17)
|
||||
assert_equal(go.g_virtual, 34)
|
||||
assert_equal(go.g_org, 0)
|
||||
assert_equal(RBA::GObject.g_inst_count, gc + 1)
|
||||
go = nil
|
||||
GC.start
|
||||
assert_equal(RBA::GObject.g_inst_count, gc)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
# extend A
|
||||
class RBA::A
|
||||
|
||||
alias_method :org_initialize, :initialize
|
||||
|
||||
def initialize(*args)
|
||||
org_initialize(*args)
|
||||
@offset = nil
|
||||
end
|
||||
def s( o )
|
||||
@offset = o
|
||||
end
|
||||
def g
|
||||
return @offset
|
||||
end
|
||||
def m
|
||||
return @offset+a1
|
||||
end
|
||||
def call_a10_prot(f)
|
||||
a10_prot(f)
|
||||
end
|
||||
def inspect
|
||||
if @offset
|
||||
@offset.to_s
|
||||
else
|
||||
"a1=" + self.a1.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@offset
|
||||
|
||||
end
|
||||
|
||||
class MyException < RuntimeError
|
||||
def initialize(s)
|
||||
super(s)
|
||||
end
|
||||
end
|
||||
|
||||
class XEdge < RBA::Edge
|
||||
def initialize
|
||||
super(RBA::Point.new(1,2), RBA::Point.new(3,4))
|
||||
end
|
||||
end
|
||||
|
||||
class RBA::E
|
||||
def m
|
||||
@m
|
||||
end
|
||||
def m=(x)
|
||||
@m = x
|
||||
end
|
||||
@m = nil
|
||||
end
|
||||
|
||||
class RBAGObject < RBA::GObject
|
||||
def initialize(z)
|
||||
super()
|
||||
@z = z
|
||||
end
|
||||
# reimplementation of "virtual int g()"
|
||||
def g
|
||||
return @z*2
|
||||
end
|
||||
end
|
||||
|
||||
class RBAGFactory < RBA::GFactory
|
||||
def initialize
|
||||
super()
|
||||
end
|
||||
# reimplementation of "virtual GObject *f(int)"
|
||||
def f(z)
|
||||
return RBAGObject::new(z)
|
||||
end
|
||||
end
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+73
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -659,6 +659,78 @@ class DBPolygon_TestClass < TestBase
|
||||
|
||||
end
|
||||
|
||||
# touches predicate
|
||||
def test_touches
|
||||
|
||||
p1 = RBA::Polygon::new(RBA::Box::new(10, 20, 30, 40))
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::Box::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Box::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::Box::new(29, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(29, 20, 40, 50)), true)
|
||||
|
||||
p1 = RBA::SimplePolygon::new(RBA::Box::new(10, 20, 30, 40))
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::Polygon::new(RBA::Box::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::SimplePolygon::new(RBA::Box::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::Box::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Box::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::Box::new(29, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::Edge::new(29, 20, 40, 50)), true)
|
||||
|
||||
p1 = RBA::DPolygon::new(RBA::DBox::new(10, 20, 30, 40))
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(29, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(29, 20, 40, 50)), true)
|
||||
|
||||
p1 = RBA::DSimplePolygon::new(RBA::DBox::new(10, 20, 30, 40))
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::DPolygon::new(RBA::DBox::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(30, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(31, 20, 40, 50))), false)
|
||||
assert_equal(p1.touches?(RBA::DSimplePolygon::new(RBA::DBox::new(29, 20, 40, 50))), true)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::DBox::new(29, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(30, 20, 40, 50)), true)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(31, 20, 40, 50)), false)
|
||||
assert_equal(p1.touches?(RBA::DEdge::new(29, 20, 40, 50)), true)
|
||||
|
||||
end
|
||||
|
||||
def test_selfRef
|
||||
|
||||
# p1 is a reference to the new'd object:
|
||||
p1 = RBA::Polygon::new(RBA::Box::new(10, 20, 30, 40)).move(10, 20)
|
||||
assert_equal(p1.to_s, "(20,40;20,60;40,60;40,40)")
|
||||
GC.start
|
||||
# after the GC cleaned up the new'd object, the reference still needs to be valid
|
||||
assert_equal(p1.to_s, "(20,40;20,60;40,60;40,40)")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+49
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -89,6 +89,27 @@ class DBTrans_TestClass < TestBase
|
||||
assert_equal( e.trans( RBA::Path::new( [ RBA::Point::new(0, 1), RBA::Point::new(2, 3) ], 10 ) ).to_s, "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
assert_equal( ( e * RBA::Path::new( [ RBA::Point::new(0, 1), RBA::Point::new(2, 3) ], 10 ) ).to_s, "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
|
||||
|
||||
# Constructor variations
|
||||
assert_equal( RBA::Trans::new().to_s, "r0 0,0" )
|
||||
assert_equal( RBA::Trans::new(1).to_s, "r90 0,0" )
|
||||
assert_equal( RBA::Trans::new(2, true).to_s, "m90 0,0" )
|
||||
assert_equal( RBA::Trans::new(2, true, RBA::Vector::new(100, 200)).to_s, "m90 100,200" )
|
||||
assert_equal( RBA::Trans::new(2, true, 100, 200).to_s, "m90 100,200" )
|
||||
assert_equal( RBA::Trans::new(RBA::Vector::new(100, 200)).to_s, "r0 100,200" )
|
||||
assert_equal( RBA::Trans::new(100, 200).to_s, "r0 100,200" )
|
||||
assert_equal( RBA::Trans::new(RBA::Trans::new(100, 200), 10, 20).to_s, "r0 110,220" )
|
||||
assert_equal( RBA::Trans::new(RBA::Trans::new(100, 200), RBA::Vector::new(10, 20)).to_s, "r0 110,220" )
|
||||
|
||||
assert_equal( RBA::DTrans::new().to_s, "r0 0,0" )
|
||||
assert_equal( RBA::DTrans::new(1).to_s, "r90 0,0" )
|
||||
assert_equal( RBA::DTrans::new(2, true).to_s, "m90 0,0" )
|
||||
assert_equal( RBA::DTrans::new(2, true, RBA::DVector::new(0.1, 0.2)).to_s, "m90 0.1,0.2" )
|
||||
assert_equal( RBA::DTrans::new(2, true, 0.1, 0.2).to_s, "m90 0.1,0.2" )
|
||||
assert_equal( RBA::DTrans::new(RBA::DVector::new(0.1, 0.2)).to_s, "r0 0.1,0.2" )
|
||||
assert_equal( RBA::DTrans::new(0.1, 0.2).to_s, "r0 0.1,0.2" )
|
||||
assert_equal( RBA::DTrans::new(RBA::DTrans::new(0.1, 0.2), 0.01, 0.02).to_s, "r0 0.11,0.22" )
|
||||
assert_equal( RBA::DTrans::new(RBA::DTrans::new(0.1, 0.2), RBA::DVector::new(0.01, 0.02)).to_s, "r0 0.11,0.22" )
|
||||
|
||||
end
|
||||
|
||||
# Magnification basics
|
||||
@@ -344,6 +365,33 @@ class DBTrans_TestClass < TestBase
|
||||
assert_equal( c.to_s, "r60 *1.5 -1,5.5" )
|
||||
assert_equal( sprintf("%g",c.angle), "60" )
|
||||
|
||||
# Constructor variations
|
||||
assert_equal( RBA::ICplxTrans::new().to_s, "r0 *1 0,0" )
|
||||
assert_equal( RBA::ICplxTrans::new(1.5).to_s, "r0 *1.5 0,0" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::Trans::new(1, false, 10, 20), 1.5).to_s, "r90 *1.5 10,20" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::Trans::new(1, false, 10, 20)).to_s, "r90 *1 10,20" )
|
||||
assert_equal( RBA::ICplxTrans::new(1.5, 80, true, RBA::Vector::new(100, 200)).to_s, "m40 *1.5 100,200" )
|
||||
assert_equal( RBA::ICplxTrans::new(1.5, 80, true, 100, 200).to_s, "m40 *1.5 100,200" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::Vector::new(100, 200)).to_s, "r0 *1 100,200" )
|
||||
assert_equal( RBA::ICplxTrans::new(100, 200).to_s, "r0 *1 100,200" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::ICplxTrans::new(100, 200)).to_s, "r0 *1 100,200" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::ICplxTrans::new(100, 200), 1.5).to_s, "r0 *1.5 150,300" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::ICplxTrans::new(100, 200), 1.5, RBA::Vector::new(10, 20)).to_s, "r0 *1.5 160,320" )
|
||||
assert_equal( RBA::ICplxTrans::new(RBA::ICplxTrans::new(100, 200), 1.5, 10, 20).to_s, "r0 *1.5 160,320" )
|
||||
|
||||
assert_equal( RBA::DCplxTrans::new().to_s, "r0 *1 0,0" )
|
||||
assert_equal( RBA::DCplxTrans::new(1.5).to_s, "r0 *1.5 0,0" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DTrans::new(1, false, 0.01, 0.02), 1.5).to_s, "r90 *1.5 0.01,0.02" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DTrans::new(1, false, 0.01, 0.02)).to_s, "r90 *1 0.01,0.02" )
|
||||
assert_equal( RBA::DCplxTrans::new(1.5, 80, true, RBA::DVector::new(0.1, 0.2)).to_s, "m40 *1.5 0.1,0.2" )
|
||||
assert_equal( RBA::DCplxTrans::new(1.5, 80, true, 0.1, 0.2).to_s, "m40 *1.5 0.1,0.2" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DVector::new(0.1, 0.2)).to_s, "r0 *1 0.1,0.2" )
|
||||
assert_equal( RBA::DCplxTrans::new(0.1, 0.2).to_s, "r0 *1 0.1,0.2" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DCplxTrans::new(0.1, 0.2)).to_s, "r0 *1 0.1,0.2" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DCplxTrans::new(0.1, 0.2), 1.5).to_s, "r0 *1.5 0.15,0.3" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DCplxTrans::new(0.1, 0.2), 1.5, RBA::DVector::new(0.01, 0.02)).to_s, "r0 *1.5 0.16,0.32" )
|
||||
assert_equal( RBA::DCplxTrans::new(RBA::DCplxTrans::new(0.1, 0.2), 1.5, 0.01, 0.02).to_s, "r0 *1.5 0.16,0.32" )
|
||||
|
||||
end
|
||||
|
||||
# Complex transformation types
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
if !$:.member?(File::dirname($0))
|
||||
$:.push(File::dirname($0))
|
||||
end
|
||||
|
||||
load("test_prologue.rb")
|
||||
|
||||
class SaveLayoutOptions_TestClass < TestBase
|
||||
|
||||
# SaveLayoutOptions tests
|
||||
def test_1
|
||||
|
||||
opt = RBA::SaveLayoutOptions::new
|
||||
|
||||
# just smoke test - no query methods, so we can't check the results
|
||||
opt.add_cell(1)
|
||||
opt.add_this_cell(1)
|
||||
opt.add_layer(1, RBA::LayerInfo::new(17, 5))
|
||||
opt.clear_cells
|
||||
opt.deselect_all_layers
|
||||
opt.select_cell(1)
|
||||
opt.select_this_cell(1)
|
||||
opt.select_all_cells
|
||||
opt.select_all_layers
|
||||
|
||||
|
||||
opt.dbu = 0.5
|
||||
assert_equal(opt.dbu, 0.5)
|
||||
|
||||
opt.scale_factor = 1.5
|
||||
assert_equal(opt.scale_factor, 1.5)
|
||||
|
||||
opt.keep_instances = false
|
||||
assert_equal(opt.keep_instances?, false)
|
||||
opt.keep_instances = true
|
||||
assert_equal(opt.keep_instances?, true)
|
||||
|
||||
opt.write_context_info = false
|
||||
assert_equal(opt.write_context_info?, false)
|
||||
opt.write_context_info = true
|
||||
assert_equal(opt.write_context_info?, true)
|
||||
|
||||
opt.no_empty_cells = false
|
||||
assert_equal(opt.no_empty_cells?, false)
|
||||
opt.no_empty_cells = true
|
||||
assert_equal(opt.no_empty_cells?, true)
|
||||
|
||||
opt.format = "CIF"
|
||||
assert_equal(opt.format, "CIF")
|
||||
opt.format = "DXF"
|
||||
assert_equal(opt.format, "DXF")
|
||||
|
||||
opt.cif_blank_separator = true
|
||||
assert_equal(opt.cif_blank_separator?, true)
|
||||
opt.cif_blank_separator = false
|
||||
assert_equal(opt.cif_blank_separator?, false)
|
||||
|
||||
opt.cif_dummy_calls = true
|
||||
assert_equal(opt.cif_dummy_calls?, true)
|
||||
opt.cif_dummy_calls = false
|
||||
assert_equal(opt.cif_dummy_calls?, false)
|
||||
|
||||
opt.dxf_polygon_mode = 2
|
||||
assert_equal(opt.dxf_polygon_mode, 2)
|
||||
|
||||
opt.gds2_libname = "MYLIB"
|
||||
assert_equal(opt.gds2_libname, "MYLIB")
|
||||
|
||||
opt.gds2_max_cellname_length = 42
|
||||
assert_equal(opt.gds2_max_cellname_length, 42)
|
||||
|
||||
opt.gds2_user_units = 0.75
|
||||
assert_equal(opt.gds2_user_units, 0.75)
|
||||
|
||||
opt.gds2_max_vertex_count = 4242
|
||||
assert_equal(opt.gds2_max_vertex_count, 4242)
|
||||
|
||||
opt.gds2_multi_xy_records = true
|
||||
assert_equal(opt.gds2_multi_xy_records, true)
|
||||
opt.gds2_multi_xy_records = false
|
||||
assert_equal(opt.gds2_multi_xy_records, false)
|
||||
|
||||
opt.gds2_no_zero_length_paths = true
|
||||
assert_equal(opt.gds2_no_zero_length_paths?, true)
|
||||
opt.gds2_no_zero_length_paths = false
|
||||
assert_equal(opt.gds2_no_zero_length_paths?, false)
|
||||
|
||||
opt.gds2_write_cell_properties = true
|
||||
assert_equal(opt.gds2_write_cell_properties?, true)
|
||||
opt.gds2_write_cell_properties = false
|
||||
assert_equal(opt.gds2_write_cell_properties?, false)
|
||||
|
||||
opt.gds2_write_file_properties = true
|
||||
assert_equal(opt.gds2_write_file_properties?, true)
|
||||
opt.gds2_write_file_properties = false
|
||||
assert_equal(opt.gds2_write_file_properties?, false)
|
||||
|
||||
opt.gds2_write_timestamps = true
|
||||
assert_equal(opt.gds2_write_timestamps?, true)
|
||||
opt.gds2_write_timestamps = false
|
||||
assert_equal(opt.gds2_write_timestamps?, false)
|
||||
|
||||
# DXF+CIF attributes are kept with GDS2
|
||||
assert_equal(opt.dxf_polygon_mode, 2)
|
||||
|
||||
opt.oasis_compression_level = 5
|
||||
assert_equal(opt.oasis_compression_level, 5)
|
||||
|
||||
opt.oasis_permissive = true
|
||||
assert_equal(opt.oasis_permissive?, true)
|
||||
opt.oasis_permissive = false
|
||||
assert_equal(opt.oasis_permissive?, false)
|
||||
|
||||
opt.oasis_recompress = true
|
||||
assert_equal(opt.oasis_recompress?, true)
|
||||
opt.oasis_recompress = false
|
||||
assert_equal(opt.oasis_recompress?, false)
|
||||
|
||||
opt.oasis_strict_mode = true
|
||||
assert_equal(opt.oasis_strict_mode?, true)
|
||||
opt.oasis_strict_mode = false
|
||||
assert_equal(opt.oasis_strict_mode?, false)
|
||||
|
||||
opt.oasis_write_cblocks = true
|
||||
assert_equal(opt.oasis_write_cblocks?, true)
|
||||
opt.oasis_write_cblocks = false
|
||||
assert_equal(opt.oasis_write_cblocks?, false)
|
||||
|
||||
opt.oasis_write_cell_bounding_boxes = true
|
||||
assert_equal(opt.oasis_write_cell_bounding_boxes?, true)
|
||||
opt.oasis_write_cell_bounding_boxes = false
|
||||
assert_equal(opt.oasis_write_cell_bounding_boxes?, false)
|
||||
|
||||
opt.oasis_write_std_properties = true
|
||||
assert_equal(opt.oasis_write_std_properties?, true)
|
||||
opt.oasis_write_std_properties = false
|
||||
assert_equal(opt.oasis_write_std_properties?, false)
|
||||
|
||||
opt.oasis_substitution_char = "+"
|
||||
assert_equal(opt.oasis_substitution_char, "+")
|
||||
|
||||
|
||||
opt.set_format_from_filename("a.gds")
|
||||
assert_equal(opt.format, "GDS2")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# KLayout Layout Viewer
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
# Copyright (C) 2006-2018 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
||||
Reference in New Issue
Block a user