-
Notifications
You must be signed in to change notification settings - Fork 9
/
lattice2ShapeCopy.py
137 lines (118 loc) · 6.4 KB
/
lattice2ShapeCopy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#***************************************************************************
#* *
#* Copyright (c) 2016 - Victor Titov (DeepSOIC) *
#* <[email protected]> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* 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 Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="ShapeCopy module for Lattice2"
__author__ = "DeepSOIC"
__url__ = ""
__doc__ = "Utility methods to copy shapes"
import FreeCAD
import Part
from lattice2GeomUtils import PlacementsFuzzyCompare
def shallowCopy(shape, extra_placement = None):
"""shallowCopy(shape, extra_placement = None): creates a shallow copy of a shape. The
copy will match by isSame/isEqual/isPartner tests, but will have an independent placement.
Supports matrix, but the matrix should be pure placement (not be mirroring)."""
copiers = {
"Vertex": lambda sh: sh.Vertexes[0],
"Edge": lambda sh: sh.Edges[0],
"Wire": lambda sh: sh.Wires[0],
"Face": lambda sh: sh.Faces[0],
"Shell": lambda sh: sh.Shells[0],
"Solid": lambda sh: sh.Solids[0],
"CompSolid": lambda sh: sh.CompSolids[0],
"Compound": lambda sh: sh.Compounds[0],
}
copier = copiers.get(shape.ShapeType)
if copier is None:
copier = lambda sh: sh.copy()
FreeCAD.Console.PrintWarning("Lattice2: shallowCopy: unexpected shape type '{typ}'. Using deep copy instead.\n".format(typ= shape.ShapeType))
ret = copier(shape)
if extra_placement is not None:
if hasattr(extra_placement, 'toMatrix'):
ret.Placement = extra_placement.multiply(ret.Placement)
elif extra_placement.determinant() - 1.0 < 1e-7:
ret.transformShape(extra_placement)
else:
raise NonPlacementMatrixError("Matrix supplied to shallowCopy must be unitary.")
return ret
def deepCopy(shape, extra_placement = None):
"""deepCopy(shape, extra_placement = None): Copies all subshapes. The copy will not match by isSame/isEqual/
isPartner tests. If matrix is provided, redirects the call to transformCopy."""
if extra_placement is not None:
if hasattr(extra_placement, 'toMatrix'):
ret = shape.copy()
ret.Placement = extra_placement.multiply(ret.Placement)
else:
ret = shallowCopy(shape)
ret.transformShape(extra_placement, True)
return ret
def transformCopy(shape, extra_placement = None):
"""transformCopy(shape, extra_placement = None): creates a deep copy shape with shape's placement applied to
the subelements (the placement of returned shape is zero). Supports matrices, including mirroring matrices."""
if extra_placement is None:
extra_placement = FreeCAD.Placement()
if hasattr(extra_placement, 'toMatrix'):
extra_placement = extra_placement.toMatrix()
ret = shape.copy()
if ret.ShapeType == "Vertex":
# oddly, on Vertex, transformShape behaves strangely. So we'll create a new vertex instead.
ret = Part.Vertex(extra_placement.multiply(ret.Point))
else:
splm = ret.Matrix
ret.Matrix = FreeCAD.Base.Matrix()
ret.transformShape(extra_placement.multiply(splm), True)
return ret
def transformCopy_Smart(shape, feature_placement):
"""transformCopy_Smart(shape, feature_placement): gets rid of shape's internal placement
(by applying transform to all its elements), and assigns feature_placement to the placement.
I.e. feature_placement is the additional transform to apply. Unlike transformCopy, creates
a shallow copy if possible. Does not support matrices."""
if shape.isNull():
return shape
if PlacementsFuzzyCompare(shape.Placement, FreeCAD.Placement()):
sh = shallowCopy(shape)
else:
sh = transformCopy(shape)
sh.Placement = feature_placement
return sh
copy_types = ["Shallow copy", "Deep copy", "Transformed deep copy"]
copy_functions = [shallowCopy, deepCopy, transformCopy]
def getCopyTypeIndex(copy_type_string):
return copy_types.index(str(copy_type_string))
def copyShape(shape, copy_type_index, extra_placement = None):
"""copyShape(shape, copy_type_index, extra_placement = None): copies a shape (or creates
a moved copy of shape, if extra_placement is given). copy_type_index should be obtained
from string by getCopyTypeIndex() function."""
global copy_functions
return copy_functions[copy_type_index](shape, extra_placement)
def transformShape(shape, extra_placement):
"""transformShape(shape, extra_placement): returns shape with extra_placement applied to it.
extra_placement must be either a Placement, or a Matrix. Matrix can be mirroring.
shallowCopy is done if Placement or a placement matrix. transformCopy is done if the matrix features mirroring."""
if hasattr(extra_placement, 'toMatrix'):
# extra_placement is a Placement
return shallowCopy(shape, extra_placement)
else:
# extra_placement is a Matrix
return transformCopy(shape, extra_placement)
class NonPlacementMatrixError(ValueError):
pass