Lattice2/lattice2ShapeCopy.py
2018-06-14 01:39:03 +03:00

138 lines
6.4 KiB
Python

#***************************************************************************
#* *
#* Copyright (c) 2016 - Victor Titov (DeepSOIC) *
#* <vv.titov@gmail.com> *
#* *
#* 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