- overwritten the Beta_8.995 branch with the Gerber_Editor_Upgrade branch
This commit is contained in:
@@ -5,13 +5,16 @@
|
||||
# MIT Licence #
|
||||
# ##########################################################
|
||||
|
||||
from shapely.geometry import LineString, Point
|
||||
from shapely.affinity import rotate
|
||||
from appParsers.ParseDXF_Spline import spline2Polyline, normalize_2
|
||||
from appParsers.ParseDXF_Spline import Vector as DxfVector
|
||||
|
||||
from shapely import LineString, Point, Polygon
|
||||
from shapely.affinity import rotate, translate, scale
|
||||
# from ezdxf.math import Vector as ezdxf_vector
|
||||
from ezdxf.math import Vec3 as ezdxf_vector
|
||||
|
||||
from appParsers.ParseFont import *
|
||||
from appParsers.ParseDXF_Spline import *
|
||||
import math
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger('base2')
|
||||
@@ -176,7 +179,7 @@ def dxfellipse2shapely(ellipse, ellipse_segments=100):
|
||||
ratio = ellipse.dxf.ratio
|
||||
|
||||
points_list = []
|
||||
major_axis = Vector(list(major_axis))
|
||||
major_axis = DxfVector(list(major_axis))
|
||||
|
||||
major_x = major_axis[0]
|
||||
major_y = major_axis[1]
|
||||
@@ -191,7 +194,7 @@ def dxfellipse2shapely(ellipse, ellipse_segments=100):
|
||||
for step in range(line_seg + 1):
|
||||
if direction == 'CW':
|
||||
major_dim = normalize_2(major_axis)
|
||||
minor_dim = normalize_2(Vector([ratio * k for k in major_axis]))
|
||||
minor_dim = normalize_2(DxfVector([ratio * k for k in major_axis]))
|
||||
vx = (major_dim[0] + major_dim[1]) * math.cos(angle)
|
||||
vy = (minor_dim[0] - minor_dim[1]) * math.sin(angle)
|
||||
x = center[0] + major_x * vx - major_y * vy
|
||||
@@ -199,7 +202,7 @@ def dxfellipse2shapely(ellipse, ellipse_segments=100):
|
||||
angle += step_angle
|
||||
else:
|
||||
major_dim = normalize_2(major_axis)
|
||||
minor_dim = (Vector([ratio * k for k in major_dim]))
|
||||
minor_dim = (DxfVector([ratio * k for k in major_dim]))
|
||||
vx = (major_dim[0] + major_dim[1]) * math.cos(angle)
|
||||
vy = (minor_dim[0] + minor_dim[1]) * math.sin(angle)
|
||||
x = center[0] + major_x * vx + major_y * vy
|
||||
|
||||
@@ -102,7 +102,7 @@ def spline2Polyline(xyz, degree, closed, segments, knots):
|
||||
# equal to the order at the ends.
|
||||
# c = order of the basis function
|
||||
# n = the number of defining polygon vertices
|
||||
# n+2 = index of x[] for the first occurence of the maximum knot vector value
|
||||
# n+2 = index of x[] for the first occurrence of the maximum knot vector value
|
||||
# n+order = maximum value of the knot vector -- $n + c$
|
||||
# x[] = array containing the knot vector
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -659,167 +659,3 @@ class Vector(list):
|
||||
"""@return the transverse component
|
||||
(R in cylindrical coordinate system)."""
|
||||
return math.sqrt(self.perp2())
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Return a random 3D vector
|
||||
# ----------------------------------------------------------------------
|
||||
# @staticmethod
|
||||
# def random():
|
||||
# cosTheta = 2.0 * random.random() - 1.0
|
||||
# sinTheta = math.sqrt(1.0 - cosTheta ** 2)
|
||||
# phi = 2.0 * math.pi * random.random()
|
||||
# return Vector(math.cos(phi) * sinTheta, math.sin(phi) * sinTheta, cosTheta)
|
||||
|
||||
# #===============================================================================
|
||||
# # Cardinal cubic spline class
|
||||
# #===============================================================================
|
||||
# class CardinalSpline:
|
||||
# def __init__(self, A=0.5):
|
||||
# # The default matrix is the Catmull-Rom spline
|
||||
# # which is equal to Cardinal matrix
|
||||
# # for A = 0.5
|
||||
# #
|
||||
# # Note: Vasilis
|
||||
# # The A parameter should be the fraction in t where
|
||||
# # the second derivative is zero
|
||||
# self.setMatrix(A)
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # Set the matrix according to Cardinal
|
||||
# #-----------------------------------------------------------------------
|
||||
# def setMatrix(self, A=0.5):
|
||||
# self.M = []
|
||||
# self.M.append([ -A, 2.-A, A-2., A ])
|
||||
# self.M.append([2.*A, A-3., 3.-2.*A, -A ])
|
||||
# self.M.append([ -A, 0., A, 0.])
|
||||
# self.M.append([ 0., 1., 0, 0.])
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # Evaluate Cardinal spline at position t
|
||||
# # @param P list or tuple with 4 points y positions
|
||||
# # @param t [0..1] fraction of interval from points 1..2
|
||||
# # @param k index of starting 4 elements in P
|
||||
# # @return spline evaluation
|
||||
# #-----------------------------------------------------------------------
|
||||
# def __call__(self, P, t, k=1):
|
||||
# T = [t*t*t, t*t, t, 1.0]
|
||||
# R = [0.0]*4
|
||||
# for i in range(4):
|
||||
# for j in range(4):
|
||||
# R[i] += T[j] * self.M[j][i]
|
||||
# y = 0.0
|
||||
# for i in range(4):
|
||||
# y += R[i]*P[k+i-1]
|
||||
#
|
||||
# return y
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # Return the coefficients of a 3rd degree polynomial
|
||||
# # f(x) = a t^3 + b t^2 + c t + d
|
||||
# # @return [a, b, c, d]
|
||||
# #-----------------------------------------------------------------------
|
||||
# def coefficients(self, P, k=1):
|
||||
# C = [0.0]*4
|
||||
# for i in range(4):
|
||||
# for j in range(4):
|
||||
# C[i] += self.M[i][j] * P[k+j-1]
|
||||
# return C
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # Evaluate the value of the spline using the coefficients
|
||||
# #-----------------------------------------------------------------------
|
||||
# def evaluate(self, C, t):
|
||||
# return ((C[0]*t + C[1])*t + C[2])*t + C[3]
|
||||
#
|
||||
# #===============================================================================
|
||||
# # Cubic spline ensuring that the first and second derivative are continuous
|
||||
# # adapted from Penelope Manual Appending B.1
|
||||
# # It requires all the points (xi,yi) and the assumption on how to deal
|
||||
# # with the second derivative on the extremities
|
||||
# # Option 1: assume zero as second derivative on both ends
|
||||
# # Option 2: assume the same as the next or previous one
|
||||
# #===============================================================================
|
||||
# class CubicSpline:
|
||||
# def __init__(self, X, Y):
|
||||
# self.X = X
|
||||
# self.Y = Y
|
||||
# self.n = len(X)
|
||||
#
|
||||
# # Option #1
|
||||
# s1 = 0.0 # zero based = s0
|
||||
# sN = 0.0 # zero based = sN-1
|
||||
#
|
||||
# # Construct the tri-diagonal matrix
|
||||
# A = []
|
||||
# B = [0.0] * (self.n-2)
|
||||
# for i in range(self.n-2):
|
||||
# A.append([0.0] * (self.n-2))
|
||||
#
|
||||
# for i in range(1,self.n-1):
|
||||
# hi = self.h(i)
|
||||
# Hi = 2.0*(self.h(i-1) + hi)
|
||||
# j = i-1
|
||||
# A[j][j] = Hi
|
||||
# if i+1<self.n-1:
|
||||
# A[j][j+1] = A[j+1][j] = hi
|
||||
#
|
||||
# if i==1:
|
||||
# B[j] = 6.*(self.d(i) - self.d(j)) - hi*s1
|
||||
# elif i<self.n-2:
|
||||
# B[j] = 6.*(self.d(i) - self.d(j))
|
||||
# else:
|
||||
# B[j] = 6.*(self.d(i) - self.d(j)) - hi*sN
|
||||
#
|
||||
#
|
||||
# self.s = gauss(A,B)
|
||||
# self.s.insert(0,s1)
|
||||
# self.s.append(sN)
|
||||
# # print ">> s <<"
|
||||
# # pprint(self.s)
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# def h(self, i):
|
||||
# return self.X[i+1] - self.X[i]
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# def d(self, i):
|
||||
# return (self.Y[i+1] - self.Y[i]) / (self.X[i+1] - self.X[i])
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# def coefficients(self, i):
|
||||
# """return coefficients of cubic spline for interval i a*x**3+b*x**2+c*x+d"""
|
||||
# hi = self.h(i)
|
||||
# si = self.s[i]
|
||||
# si1 = self.s[i+1]
|
||||
# xi = self.X[i]
|
||||
# xi1 = self.X[i+1]
|
||||
# fi = self.Y[i]
|
||||
# fi1 = self.Y[i+1]
|
||||
#
|
||||
# a = 1./(6.*hi)*(si*xi1**3 - si1*xi**3 + 6.*(fi*xi1 - fi1*xi)) + hi/6.*(si1*xi - si*xi1)
|
||||
# b = 1./(2.*hi)*(si1*xi**2 - si*xi1**2 + 2*(fi1 - fi)) + hi/6.*(si - si1)
|
||||
# c = 1./(2.*hi)*(si*xi1 - si1*xi)
|
||||
# d = 1./(6.*hi)*(si1-si)
|
||||
#
|
||||
# return [d,c,b,a]
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# def __call__(self, i, x):
|
||||
# C = self.coefficients(i)
|
||||
# return ((C[0]*x + C[1])*x + C[2])*x + C[3]
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # @return evaluation of cubic spline at x using coefficients C
|
||||
# #-----------------------------------------------------------------------
|
||||
# def evaluate(self, C, x):
|
||||
# return ((C[0]*x + C[1])*x + C[2])*x + C[3]
|
||||
#
|
||||
# #-----------------------------------------------------------------------
|
||||
# # Return evaluated derivative at x using coefficients C
|
||||
# #-----------------------------------------------------------------------
|
||||
# def derivative(self, C, x):
|
||||
# a = 3.0*C[0] # derivative coefficients
|
||||
# b = 2.0*C[1] # ... for sampling with rejection
|
||||
# c = C[2]
|
||||
# return (3.0*C[0]*x + 2.0*C[1])*x + C[2]
|
||||
#
|
||||
|
||||
1628
appParsers/ParseExcellon.py
Normal file
1628
appParsers/ParseExcellon.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,13 +15,14 @@ import os
|
||||
import sys
|
||||
import glob
|
||||
|
||||
from shapely.geometry import Polygon, MultiPolygon
|
||||
from shapely import Polygon, MultiPolygon
|
||||
from shapely.affinity import translate, scale
|
||||
|
||||
import freetype as ft
|
||||
from fontTools import ttLib
|
||||
|
||||
import logging
|
||||
|
||||
import gettext
|
||||
import appTranslation as fcTranslate
|
||||
import builtins
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
|
||||
from PyQt6 import QtWidgets
|
||||
from camlib import Geometry, arc, arc_angle, ApertureMacro, grace, flatten_shapely_geometry
|
||||
|
||||
from appParsers.ParseDXF import getdxfgeo
|
||||
from appParsers.ParseSVG import svgparselength, getsvggeo, svgparse_viewbox
|
||||
|
||||
import numpy as np
|
||||
import traceback
|
||||
from copy import deepcopy
|
||||
|
||||
from shapely.ops import unary_union, linemerge
|
||||
import shapely.affinity as affinity
|
||||
from shapely.geometry import box as shply_box
|
||||
from shapely.geometry import LinearRing, MultiLineString
|
||||
from shapely import box as shply_box
|
||||
from shapely import LinearRing, MultiLineString, LineString, Polygon, MultiPolygon, Point, prepare, is_prepared
|
||||
|
||||
from lxml import etree as ET
|
||||
import ezdxf
|
||||
|
||||
from appParsers.ParseDXF import *
|
||||
from appParsers.ParseSVG import svgparselength, getsvggeo, svgparse_viewbox
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
|
||||
import gettext
|
||||
import builtins
|
||||
@@ -505,6 +509,7 @@ class Gerber(Geometry):
|
||||
|
||||
geo_dict = {}
|
||||
geo_f = LineString(path)
|
||||
prepare(geo_f)
|
||||
if not geo_f.is_empty:
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
@@ -513,6 +518,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
if not geo_s.is_empty and geo_s.is_valid:
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -675,7 +681,7 @@ class Gerber(Geometry):
|
||||
# ################################################################
|
||||
if current_macro is None: # No macro started yet
|
||||
match = self.am1_re.search(gline)
|
||||
# Start macro if match, else not an AM, carry on.
|
||||
# Start macro if there is a match, else not an AM, carry on.
|
||||
if match:
|
||||
self.app.log.debug("Starting macro. Line %d: %s" % (line_num, gline))
|
||||
current_macro = match.group(1)
|
||||
@@ -733,8 +739,9 @@ class Gerber(Geometry):
|
||||
if not flash.is_empty:
|
||||
if self.app.options['gerber_simplification']:
|
||||
flash = flash.simplify(s_tol)
|
||||
poly_buffer.append(flash)
|
||||
|
||||
prepare(flash)
|
||||
poly_buffer.append(flash)
|
||||
if self.is_lpc is True:
|
||||
geo_dict['clear'] = flash
|
||||
else:
|
||||
@@ -784,6 +791,7 @@ class Gerber(Geometry):
|
||||
else:
|
||||
geo_dict = {}
|
||||
geo_f = LineString(path)
|
||||
prepare(geo_f)
|
||||
if not geo_f.is_empty:
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
@@ -793,6 +801,7 @@ class Gerber(Geometry):
|
||||
geo_s = LineString(path).buffer(width / 1.999, int(self.steps_per_circle))
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
prepare(geo_s)
|
||||
if not geo_s.is_empty:
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
@@ -851,6 +860,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
pol = pol.simplify(s_tol)
|
||||
|
||||
prepare(pol)
|
||||
poly_buffer.append(pol)
|
||||
if self.is_lpc is True:
|
||||
geo_dict['clear'] = pol
|
||||
@@ -865,6 +875,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
if self.is_lpc is True:
|
||||
geo_dict['clear'] = geo_s
|
||||
@@ -907,6 +918,7 @@ class Gerber(Geometry):
|
||||
geo_dict = {}
|
||||
if geo_f:
|
||||
if not geo_f.is_empty:
|
||||
prepare(geo_f)
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
if geo_s:
|
||||
@@ -916,6 +928,7 @@ class Gerber(Geometry):
|
||||
|
||||
if not geo_s.is_valid:
|
||||
print("Not valid: ", line_num)
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
if self.is_lpc is True:
|
||||
geo_dict['clear'] = geo_s
|
||||
@@ -970,7 +983,9 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
pol = pol.simplify(s_tol)
|
||||
|
||||
prepare(pol)
|
||||
pol_f = pol.exterior
|
||||
prepare(pol_f)
|
||||
if not pol_f.is_empty:
|
||||
follow_buffer.append(pol_f)
|
||||
geo_dict['follow'] = pol
|
||||
@@ -991,9 +1006,11 @@ class Gerber(Geometry):
|
||||
|
||||
region_f = region_s.exterior
|
||||
if not region_f.is_empty:
|
||||
prepare(region_f)
|
||||
follow_buffer.append(region_f)
|
||||
geo_dict['follow'] = region_f
|
||||
|
||||
prepare(region_s)
|
||||
poly_buffer.append(region_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1010,9 +1027,11 @@ class Gerber(Geometry):
|
||||
|
||||
region_f = region_s.exterior
|
||||
if not region_f.is_empty:
|
||||
prepare(region_f)
|
||||
follow_buffer.append(region_f)
|
||||
geo_dict['follow'] = region_f
|
||||
|
||||
prepare(region_s)
|
||||
poly_buffer.append(region_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1107,6 +1126,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
flash = flash.simplify(s_tol)
|
||||
|
||||
prepare(flash)
|
||||
poly_buffer.append(flash)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1136,6 +1156,7 @@ class Gerber(Geometry):
|
||||
|
||||
geo_dict = {}
|
||||
geo_f = Point([current_x, current_y])
|
||||
prepare(geo_f)
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
|
||||
@@ -1143,6 +1164,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1240,6 +1262,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1251,6 +1274,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1308,6 +1332,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1318,6 +1343,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1339,6 +1365,7 @@ class Gerber(Geometry):
|
||||
# this treats the case when we are storing geometry as paths
|
||||
geo_dict = {}
|
||||
geo_flash = Point([linear_x, linear_y])
|
||||
prepare(geo_flash)
|
||||
follow_buffer.append(geo_flash)
|
||||
geo_dict['follow'] = geo_flash
|
||||
|
||||
@@ -1353,6 +1380,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
flash = flash.simplify(s_tol)
|
||||
|
||||
prepare(flash)
|
||||
poly_buffer.append(flash)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1422,7 +1450,8 @@ class Gerber(Geometry):
|
||||
j = 0
|
||||
|
||||
if quadrant_mode is None:
|
||||
self.app.log.error("Found arc without preceding quadrant specification G74 or G75. (%d)" % line_num)
|
||||
self.app.log.error(
|
||||
"Found arc without preceding quadrant specification G74 or G75. (%d)" % line_num)
|
||||
self.app.log.error(gline)
|
||||
continue
|
||||
|
||||
@@ -1457,6 +1486,7 @@ class Gerber(Geometry):
|
||||
# this treats the case when we are storing geometry as paths
|
||||
geo_f = LineString(path)
|
||||
if not geo_f.is_empty:
|
||||
prepare(geo_f)
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
|
||||
@@ -1466,6 +1496,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
buffered = buffered.simplify(s_tol)
|
||||
|
||||
prepare(buffered)
|
||||
poly_buffer.append(buffered)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1609,6 +1640,7 @@ class Gerber(Geometry):
|
||||
# this treats the case when we are storing geometry as paths
|
||||
geo_f = LineString(path)
|
||||
if not geo_f.is_empty:
|
||||
prepare(geo_f)
|
||||
follow_buffer.append(geo_f)
|
||||
geo_dict['follow'] = geo_f
|
||||
|
||||
@@ -1619,6 +1651,7 @@ class Gerber(Geometry):
|
||||
if self.app.options['gerber_simplification']:
|
||||
geo_s = geo_s.simplify(s_tol)
|
||||
|
||||
prepare(geo_s)
|
||||
poly_buffer.append(geo_s)
|
||||
|
||||
if self.is_lpc is True:
|
||||
@@ -1678,6 +1711,10 @@ class Gerber(Geometry):
|
||||
new_poly = new_poly.buffer(0, int(self.steps_per_circle))
|
||||
self.app.log.warning("Union done.")
|
||||
|
||||
# #########################################################################################################
|
||||
prepare(new_poly)
|
||||
# #########################################################################################################
|
||||
|
||||
if current_polarity == 'D':
|
||||
self.app.inform.emit('%s' % _("Gerber processing. Applying Gerber polarity."))
|
||||
if new_poly.is_valid:
|
||||
@@ -1722,6 +1759,13 @@ class Gerber(Geometry):
|
||||
# flatten the solid geometry
|
||||
self.solid_geometry = flatten_shapely_geometry(self.solid_geometry)
|
||||
|
||||
# import time
|
||||
# start = time.time()
|
||||
# #########################################################################################################
|
||||
prepare(self.solid_geometry)
|
||||
# #########################################################################################################
|
||||
# print(f"Time elapsed: {time.time() - start}; Is prepared? {is_prepared(self.solid_geometry)}")
|
||||
|
||||
if self.app.options['gerber_clean_apertures']:
|
||||
# clean the Gerber file of apertures with no geometry
|
||||
for apid, apvalue in list(self.tools.items()):
|
||||
@@ -1762,7 +1806,7 @@ class Gerber(Geometry):
|
||||
maxx = loc[0] + width / 2
|
||||
miny = loc[1] - height / 2
|
||||
maxy = loc[1] + height / 2
|
||||
return shply_box(minx, miny, maxx, maxy)
|
||||
return shply_box(minx, miny, maxx, maxy).buffer(0.0000001)
|
||||
|
||||
if aperture['type'] == 'O': # Obround
|
||||
loc = location.coords[0]
|
||||
@@ -1959,7 +2003,7 @@ class Gerber(Geometry):
|
||||
self.app.log.debug("appParsers.ParseGerber.Gerber.import_svg(). Finished parsing the SVG geometry.")
|
||||
|
||||
if flip:
|
||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||
geos = [affinity.translate(affinity.scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||
self.app.log.debug("appParsers.ParseGerber.Gerber.import_svg(). SVG geometry was flipped.")
|
||||
|
||||
# Add to object
|
||||
@@ -2008,6 +2052,7 @@ class Gerber(Geometry):
|
||||
}
|
||||
|
||||
for pol in self.solid_geometry:
|
||||
prepare(pol)
|
||||
new_el = {'solid': pol, 'follow': LineString(pol.exterior.coords)}
|
||||
self.tools[0]['geometry'].append(new_el)
|
||||
|
||||
@@ -2065,6 +2110,7 @@ class Gerber(Geometry):
|
||||
flat_geo = list(self.flatten_list(self.solid_geometry))
|
||||
if flat_geo:
|
||||
self.solid_geometry = unary_union(flat_geo)
|
||||
prepare(self.solid_geometry)
|
||||
self.follow_geometry = self.solid_geometry
|
||||
else:
|
||||
return "fail"
|
||||
@@ -2529,7 +2575,7 @@ class Gerber(Geometry):
|
||||
try:
|
||||
if isinstance(self.solid_geometry, (MultiPolygon, MultiLineString)):
|
||||
self.geo_len = len(self.solid_geometry.geoms)
|
||||
else:
|
||||
if isinstance(self.solid_geometry, list):
|
||||
self.geo_len = len(self.solid_geometry)
|
||||
except (TypeError, ValueError, RuntimeError):
|
||||
self.geo_len = 1
|
||||
@@ -2634,8 +2680,8 @@ class Gerber(Geometry):
|
||||
geo_p = shply_box(minx, miny, maxx, maxy)
|
||||
new_geo_el['solid'] = geo_p
|
||||
else:
|
||||
self.app.log.debug("appParsers.ParseGerber.Gerber.buffer() --> "
|
||||
"ap type not supported")
|
||||
self.app.log.debug(
|
||||
"appParsers.ParseGerber.Gerber.buffer() --> ap type not supported")
|
||||
else:
|
||||
new_geo_el['solid'] = geo_el['follow'].buffer(
|
||||
size/1.9999,
|
||||
|
||||
@@ -16,9 +16,8 @@ from copy import deepcopy
|
||||
import sys
|
||||
|
||||
from shapely.ops import unary_union
|
||||
from shapely.geometry import LineString, Point
|
||||
from shapely import LineString, Point
|
||||
|
||||
# import AppTranslation as fcTranslate
|
||||
import gettext
|
||||
import builtins
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from PyQt6 import QtCore
|
||||
|
||||
from appCommon.Common import GracefulException as grace
|
||||
|
||||
from shapely.geometry import Polygon, LineString, MultiPolygon
|
||||
from shapely import Polygon, LineString, MultiPolygon
|
||||
|
||||
from copy import copy, deepcopy
|
||||
import numpy as np
|
||||
|
||||
@@ -24,7 +24,7 @@ from svg.path import Line, Arc, CubicBezier, QuadraticBezier, parse_path
|
||||
# from svg.path.path import Move
|
||||
# from svg.path.path import Close
|
||||
import svg.path
|
||||
from shapely.geometry import LineString, MultiLineString, Point
|
||||
from shapely import LineString, MultiLineString, Point
|
||||
from shapely.affinity import skew, affine_transform, rotate
|
||||
import numpy as np
|
||||
|
||||
|
||||
Reference in New Issue
Block a user