# python3
# FLC 2013
import math
import numpy as np
import numbers
import tikzpy.obj_data as obj_data
import csv
[docs]class _points(object):
"""**Points class:**
.. _points_cls:
:platform: Unix, Windows
:synopsis: Allows to add, operate and edit points in a 3D space
:properties:
* Get a point by unique id. (pto = tikzpy.pto[id])
* Set a point by unique id. (tikzpy.pto[id]=pto). When set just the coordinates are changed.
* Iterate points as point object
**Chracteristics of a point (pto) object**
:ivar id: get unique id of the point
:ivar alias: set/get alias name of the point
:ivar x: set/get x coordinate property
:ivar y: set/get y coordinate property
:ivar z: set/get z coordinate property
:ivar xyz: set/get the three coordinates
:ivar layer: set/get layer member property
:ivar info: get formated text with point info
:Operations:
* **equality (pto1 == pto2):** check the three coordinates are the same
* **sum (pto1 + pto2):** allow to sum to points as it were two vectors
* **sum (pto1 + real):** sum to all the coordinates the real number
* **diff (pto1 - pto2):** allow to subtracts to points as it were two vectors
* **diff (pto1 - real):** substract to all the coordinates the real number
* **multiplication (pto1 * pto2):** multiplicate each coordinate by the other
* **multiplication (pto1 * real):** multiplicate each coordinate by the real number
* **print (print pto1):** prints the point info
* **copy (pto3 = pto1.copy(alias)):** deepcopy of a point (diferent unique id)
"""
"""
Future functions:
* Export points to csv and txt file (separate by ;)
* Assign to list of points, x, y, z independently
----------- Done ----------------------
* Add scale of ptos -- July 2016
* Translation of a point function -- April 2016
* Rotation of a point function -- April 2016
* Show points -- April 2016
* Import points to csv and txt file (separate by ;) -- July 2016
* read_list_csv, ptos, middle_point, ptos_distance -- August 2017
"""
def __init__(self, parent):
self.parent = parent
self.auto_save_aux = False
### Counters
self.counters = obj_data._clsdata(type = int(0))
### Dictionary of points
self.points = obj_data._clsdata(type = [])
self.counters["points"] = 0
###################################### Internal
def __getitem__(self, key):
return self.point(key)
def __setitem__(self, key, other_point):
porigin = self.point(key)
if isinstance(other_point, porigin.__class__):
porigin.x = other_point.x
porigin.y = other_point.y
porigin.z = other_point.z
else:
pass
def point(self, key):
### Give a point
_key = str(key)
if self.points[_key]:
return _point(self,_key)
else:
return None
def _type_of_point(self):
### Returns the type of point
return type(_point(self,None))
def _choices(self, v):
### returns the point object, v types: as id, alias or point
if type(v) == type(""):
#empty name
if v == "":
self.parent.error("Wrong point format while adding a point, empty string. In addpto.", ref = "")
#id or alias
if v[0] == "#":
pt = self.parent.pto[v]
else:
pt = self.parent.pto.alias(v)
#return point
if pt is None:
self.parent.error("Wrong point format while adding a point, empty string. In addpto.", ref = "")
else:
return pt
elif type(v) == self.parent.pto._type_of_point():
return v
else:
self.parent.error("Wrong point format while adding a point. In addpto.", ref = "")
def _check_alias(self, alias):
### Check alias possibilities
if alias == "":
return True
if type(alias) == type(""):
if alias[0] == "#":
self.parent.error("Alias name can not start with a # character. In _check_alias")
else:
if self.alias(alias) is None:
return True
else:
self.parent.error("Alias already exist. In _check_alias")
else:
self.parent.error("Alias of point is not a string value. In _check_alias")
def _point_format(self, x, y, z = 0, layer = 0, alias = ""):
### Bottle neck point
self._check_alias(alias)
return [x,y,z,[int(layer)],str(alias)]
def addpoint(self, x, y, z = 0, layer = 0, alias = ""):
# Create new point
_key = "#%i" % self.counters["points"]
self.counters["points"] = self.counters["points"] + 1
self.points[_key] = self._point_format(x, y, z = z , layer = layer, alias = alias)
return self.point(_key)
def auxpoint(self, x=0, y=0, z = 0, layer = 0):
# Create new auxiliary
lst = self._point_format(x, y, z = z , layer = layer)
p = _point(self, None, lst)
if self.auto_save_aux: p.save()
return p
###################################### Functions
[docs] def pto(self, x=0, y=0, z=0, layer = 0, alias = ""):
"""
.. _points_pto:
**Synopsis:**
* Add a new point
**Args:**
* x=0: x coordinate
* y=0: y coordinate
* z=0: z coordinate
* layer = 0: layer member
* alias = "": alias name
**Returns:**
* A point object with the x, y, z, layer and name properties
.. note::
* See example
"""
return self.addpoint(x, y, z = z, layer = layer, alias = alias)
[docs] def aux(self, x=0, y=0, z = 0, layer = 0):
"""
.. _points_aux:
**Synopsis:**
* Add an new auxiliary point
**Args:**
* x=0: x coordinate
* y=0: y coordinate
* z=0: z coordinate
* layer = 0: layer member
**Returns:**
* A point object with the x, y, z, layer and name properties
.. note::
* Auxiliary points do not have unique id
* Atribute .save() asign a unique id to an auxiliary point
"""
return self.auxpoint(x=x, y=y, z = z, layer = layer)
[docs] def alias(self, alias):
"""
.. _alias:
**Synopsis:**
* Return a point by alias
**Args:**
* alias: point alias
**Returns:**
* The first point object with such alias
.. note::
* Alias can be empty or be a unique identification. Can not start with a **#** character.
"""
for ii in range(0,self.counters["points"]):
_key = "#%i" % ii
p = self.point(_key)
if p is not None:
if p.alias == str(alias): return p
return None
[docs] def translate(self, ptos, x = 0., y = 0., z = 0.):
"""
.. _pto_translate:
**Synopsis:**
* Translate a point of list of points in a 3D space
**Args:**
* ptos: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
**Optional parameters:**
* x = 0: increment in x coordinate to tranlate
* y = 0: increment in y coordinate to tranlate
* z = 0: increment in z coordinate to tranlate
**Returns:**
* None
.. note::
* See :ref:`addpto examples <ex_shapes_addpto>`
* See :ref:`example 3 <ex_points_ex3>`
"""
if type(ptos) is type([]):
for v in ptos:
_pto = self._choices(v)
_pto.x = _pto.x + x
_pto.y = _pto.y + y
_pto.z = _pto.z + z
else:
_pto = self._choices(ptos)
_pto.x = _pto.x + x
_pto.y = _pto.y + y
_pto.z = _pto.z + z
[docs] def translate_to(self, ptos, pto_ref, pto_ref_final):
"""
.. _pto_translate_to:
**Synopsis:**
* Given a reference point and a final position for such point. Translate a point or list of points in a 3D space in a similar manner.
**Args:**
* ptos: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
**Optional parameters:**
* pto_ref: reference point
* pto_ref_final: final refence point position
**Returns:**
* None
.. note::
* See :ref:`addpto examples <ex_shapes_addpto>`
* See :ref:`example 3 <ex_points_ex3>`
"""
ix = pto_ref_final.x - pto_ref.x
iy = pto_ref_final.y - pto_ref.y
iz = pto_ref_final.z - pto_ref.z
if type(ptos) is type([]):
for v in ptos:
_pto = self._choices(v)
_pto.x = _pto.x + ix
_pto.y = _pto.y + iy
_pto.z = _pto.z + iz
else:
_pto = self._choices(ptos)
_pto.x = _pto.x + ix
_pto.y = _pto.y + iy
_pto.z = _pto.z + iz
[docs] def rotate(self, ptos, pto_rotation, Ax = 0., Ay = 0., Az = 0.):
"""
.. _pto_rotate:
**Synopsis:**
* Rotate a point or list of points in a 3D space respect an origin point
**Args:**
* ptos: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
* pto_rotation: center point of rotation
**Optional parameters:**
* Ax = 0.: yaw angle in degrees to turn respect axis X
* Ay = 0.: pitch angle in degrees to turn respect axis Y
* Az = 0.: roll angle in degrees to turn respect axis Z
**Returns:**
* None
.. note::
* See :ref:`addpto examples <ex_shapes_addpto>`
* See :ref:`example 3 <ex_points_ex3>`
"""
def _rotation_matrix(Ax,Ay,Az):
AAx,AAy,AAz = Ax*np.pi/180.,Ay*np.pi/180.,Az*np.pi/180.
Rx = np.matrix([[1.,0.,0.], [0.,np.cos(AAx),-np.sin(AAx)], [0., np.sin(AAx), np.cos(AAx)]])
Ry = np.matrix([[np.cos(AAy),0.,np.sin(AAy)], [0.,1.,0.], [-np.sin(AAy), 0., np.cos(AAy)]])
Rz = np.matrix([[np.cos(AAz),-np.sin(AAz),0.], [np.sin(AAz),np.cos(AAz),0.], [0., 0., 1.]])
return (Rx*Ry)*Rz
def _rotate(self,_pto,pto_rotation,R):
#Tranlate to oringin
if type(pto_rotation) == self._type_of_point():
trans = pto_rotation
tx,ty,tz = trans.x,trans.y,trans.z
self.translate(_pto, x = -tx, y = -ty, z = -tz)
else:
self.parent.error("Origing point in translate not a point")
#Rotate
x, y, z = _pto.x, _pto.y, _pto.z
_pto.x = x * R[0,0] + y * R[0,1] + z * R[0,2]
_pto.y = x * R[1,0] + y * R[1,1] + z * R[1,2]
_pto.z = x * R[2,0] + y * R[2,1] + z * R[2,2]
#Un-translate to origin
if type(pto_rotation) == self._type_of_point():
self.translate(_pto, x = tx, y = ty, z = tz)
### Check lists
R = _rotation_matrix(Ax,Ay,Az)
if type(ptos) is type([]):
for v in ptos:
_pto = self._choices(v)
_rotate(self,_pto,pto_rotation,R)
else:
_pto = self._choices(ptos)
_rotate(self,_pto,pto_rotation,R)
[docs] def scale(self, ptos, Sx = 1., Sy = 1., Sz = 1., pto_origin= None):
"""
.. _pto_scale:
**Synopsis:**
* Scale a point or list of points in a 3D space respect an origin point
**Args:**
* ptos: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
**Optional parameters:**
* Sx = 1.: scale in axis X
* Sy = 1.: scale in axis Y
* Sz = 1.: scale in axis Z
* pto_origin = None: center point of scaling, if None origin is global origin
**Returns:**
* None
.. note::
* See :ref:`addpto examples <ex_shapes_addpto>`
* See :ref:`example 4 <ex_points_ex4>`
"""
def _scale(self,_pto,pto_origin,Sx,Sy,Sz):
#Tranlate to oringin
if pto_origin is not None:
if type(pto_origin) == self._type_of_point():
trans = pto_origin
tx,ty,tz = trans.x,trans.y,trans.z
self.translate(_pto, x = tx, y = ty, z = tz)
else:
self.parent.error("Origing point in translate not a point")
#Scale
x, y, z = _pto.x, _pto.y, _pto.z
_pto.x = x * Sx
_pto.y = y * Sy
_pto.z = z * Sz
#Un-translate to origin
if pto_origin is not None:
if type(pto_origin) == self._type_of_point():
self.translate(_pto, x = -tx, y = -ty, z = -tz)
if type(ptos) is type([]):
for v in ptos:
_pto = self._choices(v)
_scale(self,_pto,pto_origin,Sx,Sy,Sz)
else:
_pto = self._choices(ptos)
_scale(self,_pto,pto_origin,Sx,Sy,Sz)
[docs] def copy(self, ptos, alias_prefix = "", alias_sufix = ""):
"""
.. _pto_copy:
**Synopsis:**
* Returns a copy of the list of points
**Args:**
* ptos: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
**Optional parameters:**
* alias_sufix = "": Add a sufix to the alias of each point
* alias_prefix = "": Add a prefix to the alias of each point
**Returns:**
* List of points copied (ids), with the alias modified
.. note::
* If alias_sufix and alias_prefix is "", an empty alias for each copied point is return
* See :ref:`addpto examples <ex_shapes_addpto>`
* See :ref:`example 3 <ex_points_ex3>`
"""
lst_out = []
if len(ptos) == 0: return []
if type(ptos) is type([]):
for v in ptos:
_pto = self._choices(v)
_alias = _pto.alias
if alias_prefix != "" and type(alias_prefix) == type(""):
_alias = alias_prefix + _alias
if alias_sufix != "" and type(alias_sufix) == type(""):
_alias = _alias + alias_sufix
if _alias == _pto.alias: _alias = ""
lst_out.append(_pto.copy(alias = _alias).id)
else:
_pto = self._choices(ptos)
_alias = _pto.alias
if alias_prefix != "" and type(alias_prefix) == type(""):
_alias = alias_prefix + _alias
if alias_sufix != "" and type(alias_sufix) == type(""):
_alias = _alias + alias_sufix
if _alias == _pto.alias: _alias = ""
lst_out.append(_pto.copy(alias = _alias).id)
return lst_out
[docs] def draw_points(self, ptos = None, mark_radius = 1, color = "", label = "#marker_points", layer = -1e-10):
"""
.. _draw_points:
**Synopsis:**
* Draw a list of points with a marker
* If no list of points is given, all the points are draw with a marker
**Args:**
* ptos = None: multiple points. Can be set as a point, a list o points, an alias or a list of alias. See :ref:`addpto examples <ex_shapes_addpto>`
**Optional parameters:**
* mark_radius = 1: scale of marker size
* color = "": color of the marker
* label = "#marker_points": label added to the markers
* layer = -1e-10: layer were the markers belong
**Returns:**
* None
.. note::
* See :ref:`example 3 <ex_points_ex3>`
"""
if ptos is None:
ptos = self._all_points()
self._draw_list_points(ptos, mark_radius = mark_radius, \
color = color, label = label, layer = layer)
return None
[docs] def read_list_csv(self, file_path, delimiter = None):
"""
.. _read_list_csv:
**Synopsis:**
* Read list of points in csv file
* Rows layout: x, y, z, alias, layer
**Args:**
* file_path: Full path to csv file.
**Optional parameters:**
* delimiter = None: columns separator
**Returns:**
* List of points ids ptos
.. note::
* See :ref:`example 4 <ex_points_ex4>`
"""
alias = None
layer = 0
ptos = []
with open(file_path, newline='') as csvfile:
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
# ... process CSV file contents here ...
for row in reader:
if len(row) == 2:
[x, y] = row
z = 0
elif len(row) == 3:
[x, y, z] = row
elif len(row) == 4:
[x, y, z, alias] = row
elif len(row) == 5:
[x, y, z, alias, layer] = row
else:
self.parent.error("CSV file, incorrect number of rows.", ref = "read_list_csv")
# Create a point
if alias is not None:
p = self.pto(x, y, z, layer=layer, alias=alias)
else:
p = self.pto(x, y, z, layer=layer)
# List of points
ptos.append(p.id)
return ptos
[docs] def ptos(self, x, y, z = None, layer=None, alias=''):
"""
.. _pto_ptos:
**Synopsis:**
* Returns a list of points build with the x, y, z coordinates 1D arrays
**Args:**
* x: 1D array or list, coordinate x
* y: 1D array or list, coordinate y
**Optional parameters:**
* z = None: 1D array or list, coordinate z. If None, fills z coordinate with 0, else with the number or with a given list.
* layer = None: 1D array or list, layers. If None, fills layer with 0, else with the number or with a given list.
* alias = '': 1D array or list, alias. If None, fills alias with '', else with a given list (all alias must be different if not '').
**Returns:**
* List of points ids ptos
.. note::
* All 1D array or list should be of the same size
* None
"""
def check_np_array(val):
if type(val) is type(np.array([0])):
return val.tolist()
else:
return val
_x = check_np_array(x)
_y = check_np_array(y)
_z = check_np_array(z)
_alias = check_np_array(alias)
_layer = check_np_array(layer)
if type(_x) is not type([]): self.parent.error("x is not a lists", ref = "ptos")
if type(_y) is not type([]): self.parent.error("y is not a lists", ref = "ptos")
if _z is None:
_z = [0.] * len(x)
else:
if type(_z) is not type([]):
_z = [_z] * len(x)
else:
_z = _z
if _layer is None:
_layer = [0.] * len(x)
else:
if type(z) is not type([]):
_layer = [_layer] * len(x)
else:
_layer = _layer
if type(_alias) is None:
_alias = [''] * len(x)
else:
if type(z) is not type([]):
_alias = [''] * len(x)
else:
_alias = _alias
len_x = len(_x)
len_y = len(_y)
len_z = len(_z)
len_alias = len(_alias)
len_layer = len(_layer)
if len_x != len_y: self.parent.error("x and y different size", ref = "ptos")
if len_x != len_z: self.parent.error("x and y different size", ref = "ptos")
if len_x != len_alias: self.parent.error("alias and y different size", ref = "ptos")
if len_x != len_layer: self.parent.error("layer and y different size", ref = "ptos")
ptos = []
for ii in range(0, len_x):
p = self.pto(_x[ii], _y[ii], _z[ii], layer=_layer[ii], alias=_alias[ii])
ptos.append(p)
return ptos
[docs] def middle_point(self, p1, p2, layer=0, alias=""):
"""
.. _pto_middle_point:
**Synopsis:**
* Return a middle point between p1 and p2
**Args:**
* pto1: point one
* pto2: point two
**Optional parameters:**
* layer = 0: layer member new point
* alias = "": alias name new point
**Returns:**
* Point at the middle distance
.. note::
* None
"""
x = (p1.x + p2.x)/2.
y = (p1.y + p2.y)/2.
z = (p1.z + p2.z)/2.
p = self.pto(x, y, z, layer=layer, alias=alias)
return p
[docs] def ptos_distance(self, p1, p2):
"""
.. _pto_ptos_distance:
**Synopsis:**
* Distance between p1 and p2
**Args:**
* pto1: point one
* pto2: point two
**Optional parameters:**
* None
**Returns:**
* Distance between two points
.. note::
* None
"""
x = (p1.x - p2.x)**2.
y = (p1.y - p2.y)**2.
z = (p1.z - p2.z)**2.
return (x + y + z)**0.5
###################################### Internal
def _all_points(self):
### Return a list with all points
lst_out = []
### Check all points
for key, value in self.points._data.items():
if key[0] == "#":
p = self.point(key)
lst_out.append(p.id)
### Call all shapes
for key, value in self.parent.shp.shapes._data.items():
if key[0] == "#":
for p in self.parent.shp[key].addpto:
if p.id in lst_out:
pass
else:
lst_out.append(p)
return lst_out
def _canavas_size(self, ptos):
### Return canavas cube from a list of points [[max_x,_min_x],[max_y,_min_y],[max_z,_min_z]]
def _max_min_canavas(_canavas, x, y, z):
# [[max_x,min_x],[max_y,min_y],[max_z,min_z]] = self._canavas
#_canavas = [[0.,0.],[0.,0.],[0.,0.]]
if x > _canavas[0][1]: _canavas[0][1] = x
if x < _canavas[0][0]: _canavas[0][0] = x
if y > _canavas[1][1]: _canavas[1][1] = y
if y < _canavas[1][0]: _canavas[1][0] = y
if z > _canavas[2][1]: _canavas[2][1] = z
if z < _canavas[2][0]: _canavas[2][0] = z
return _canavas
start = True
# Iterate list of points
if type(ptos) is type([]):
for pto in ptos:
p = self._choices(pto)
if start:
start = False
_canavas = [[p.x,p.x],[p.y,p.y],[p.z,p.z]]
else:
_canavas = _max_min_canavas(_canavas, p.x, p.y, p.z)
else:
p = self._choices(ptos)
if start:
start = False
_canavas = [[p.x,p.x],[p.y,p.y],[p.z,p.z]]
else:
_canavas = _max_min_canavas(_canavas, p.x, p.y, p.z)
### Get values
[[min_x,max_x],[min_y,max_y],[min_z,max_z]] = _canavas
### Space lengths
size_x, size_y, size_z = max_x - min_x, max_y - min_y, max_z - min_z
### Max length
max_size = abs(size_x)
if abs(size_y) > max_size: max_size = size_y
if abs(size_z) > max_size: max_size = size_z
return size_x, size_y, size_z, max_size, _canavas
def _draw_list_points(self, ptos, mark_radius = 1, color = "", label = "#marker_points", layer = -1e-10):
### Draw markers for a list of points
# Find max sizes of drawing. Canavas
size_x, size_y, size_z, max_size, _canavas = self._canavas_size(ptos)
s = max_size / 200.
s_mark_radius = mark_radius * s
# draw marker
def _draw_marker(self, pto, mark_radius, color, layer, label):
if pto.id is None: return
x,y,z = pto.x,pto.y,pto.z
p1 = self.auxpoint(x=x+mark_radius, y=y, z=z, layer = layer)
p2 = self.auxpoint(x=x-mark_radius, y=y, z=z, layer = layer)
l = self.parent.shp.line(p1,p2,color=color,layer=layer)
l.addlabel = label
p1 = self.auxpoint(x=x, y=y+mark_radius, z=z, layer = layer)
p2 = self.auxpoint(x=x, y=y-mark_radius, z=z, layer = layer)
l = self.parent.shp.line(p1,p2,color=color,layer=layer)
l.addlabel = label
p1 = self.auxpoint(x=x, y=y, z=z+mark_radius, layer = layer)
p2 = self.auxpoint(x=x, y=y, z=z-mark_radius, layer = layer)
l = self.parent.shp.line(p1,p2,color=color,layer=layer)
l.addlabel = label
# Iterate list of points
if type(ptos) is type([]):
for pto in ptos:
_p = self._choices(pto)
_draw_marker(self, _p, s_mark_radius, color, layer, label)
else:
_p = self._choices(ptos)
_draw_marker(self, _p, s_mark_radius, color, layer, label)
#################################################
################# Point object ##################
#################################################
class _point(object):
def __init__(self, parent, key, lst = []):
self.parent = parent
self._key = key
self._lst = lst
######################## Operators
def __eq__(self, other):
### equality
if isinstance(other, self.__class__):
if self.x == other.x:
if self.y == other.y:
if self.z == other.z:
return True
return False
else:
return False
def __ne__(self, other):
### not equality
return not self.__eq__(other)
def _add(self, other):
### summatory
if isinstance(other, self.__class__):
p = self.parent.auxpoint()
p.x = self.x + other.x
p.y = self.y + other.y
p.z = self.z + other.z
p.layer = self.layer
return p
elif isinstance(other, numbers.Real):
p = self.parent.auxpoint()
p.x = self.x + self._valchnage(other)
p.y = self.y + self._valchnage(other)
p.z = self.z + self._valchnage(other)
p.layer = self.layer
return p
else:
return None
def __add__(self, other):
### summatory
return self._add(other)
def __radd__(self, other):
### difference
return self._add(other)
def __sub__(self, other) :
### substraction
if isinstance(other, self.__class__):
p = self.parent.auxpoint()
p.x = self.x - other.x
p.y = self.y - other.y
p.z = self.z - other.z
p.layer = self.layer
return p
elif isinstance(other, numbers.Real):
p = self.parent.auxpoint()
o = self._valchnage(other)
p.x = self.x - o
p.y = self.y - o
p.z = self.z - o
p.layer = self.layer
return p
else:
return None
def __rsub__(self, other) :
### reverse substraction
if isinstance(other, self.__class__):
p = self.parent.auxpoint()
p.x = other.x - self.x
p.y = other.y - self.y
p.z = other.z - self.z
p.layer = self.layer
return p
elif isinstance(other, numbers.Real):
p = self.parent.auxpoint()
o = self._valchnage(other)
p.x = o - self.x
p.y = o - self.y
p.z = o - self.z
p.layer = self.layer
return p
else:
return None
def _mul(self, other) :
### multiplication
if isinstance(other, self.__class__):
p = self.parent.auxpoint()
if self.id == other.id: p = self
p.x = self.x * other.x
p.y = self.y * other.y
p.z = self.z * other.z
p.layer = self.layer
return p
elif isinstance(other, numbers.Real):
p = self.parent.auxpoint()
o = self._valchnage(other)
p.x = self.x * o
p.y = self.y * o
p.z = self.z * o
p.layer = self.layer
return p
else:
return None
def __mul__(self, other) :
### multiplication
return self._mul(other)
def __rmul__(self, other) :
### reverse multiplication
return self._mul(other)
def __repr__(self):
return self.id
def __str__(self):
return self.info
######################## Functions
def save(self):
p = self.parent.addpoint(self.x, self.y, z = self.z , layer = self.layer, alias = self.alias)
self._key = p.id
return p
def copy(self, alias = ""):
if self._key is not None:
if alias == "" or alias is None:
p = self.parent.addpoint(self.x, self.y, z = self.z , layer = self.layer)
else:
p = self.parent.addpoint(self.x, self.y, z = self.z , layer = self.layer, alias = alias)
else:
p = self.parent.auxpoint(self.x, self.y, z = self.z , layer = self.layer)
return p
def __deepcopy__(self, memo):
return self.copy()
######################## Properties
def _valchnage(self,val):
return float(val)
@property
def id(self):
if self._key is None:
return None
else:
return self._key
@property
def info(self):
return "Point key:%s x=%.4f y=%.4f z=%.4f layer=%i alias=%s NumPoints:%i" % (self.id, self.x, self.y, self.z, self.layer, self.alias,len(self.parent.points))
@property
def x(self):
if self._key is None:
return self._lst[0]
else:
return float(self.parent.points[self._key][0])
@x.setter
def x(self, value):
if self._key is None:
self._lst[0] = self._valchnage(value)
else:
self.parent.points[self._key][0] = self._valchnage(value)
@property
def y(self):
if self._key is None:
return self._lst[1]
else:
return float(self.parent.points[self._key][1])
@y.setter
def y(self, value):
if self._key is None:
self._lst[1] = self._valchnage(value)
else:
self.parent.points[self._key][1] = self._valchnage(value)
@property
def z(self):
if self._key is None:
return self._lst[2]
else:
return float(self.parent.points[self._key][2])
@z.setter
def z(self, value):
if self._key is None:
self._lst[2] = self._valchnage(value)
else:
self.parent.points[self._key][2] = self._valchnage(value)
@property
def xyz(self):
return self.parent.points[self._key][0],self.parent.points[self._key][1],self.parent.points[self._key][2]
@xyz.setter
def xyz(self, value):
if isinstance(value, self.__class__):
if self._key is None:
self.x = self._valchnage(value.x)
self.y = self._valchnage(value.y)
self.z = self._valchnage(value.z)
else:
self.parent.points[self._key][0] = self._valchnage(value.x)
self.parent.points[self._key][1] = self._valchnage(value.y)
self.parent.points[self._key][2] = self._valchnage(value.z)
else:
pass
@property
def layer(self):
if self._key is None:
return self._lst[3][0]
else:
return self.parent.points[self._key][3][0]
@layer.setter
def layer(self, value):
if self._key is None:
self._lst[3][0] = self._valchnage(value)
else:
self.parent.points[self._key][3][0] = self._valchnage(value)
@property
def alias(self):
if self._key is None:
return self._lst[4]
else:
return self.parent.points[self._key][4]
@alias.setter
def alias(self, value):
if self._key is None:
self._lst[4] = value
else:
self.parent.points[self._key][4] = value