Merge branch 'shallow_copy'

This commit is contained in:
DeepSOIC 2016-08-21 20:56:14 +03:00
commit 3769ea460a
6 changed files with 130 additions and 12 deletions

View File

@ -6,3 +6,4 @@ import lattice2GeomUtils as GeomUtils
import lattice2InterpolatorUtil as InterpolatorUtil
import lattice2Markers as Markers
import lattice2ValueSeriesGenerator as ValueSeriesGenerator
import lattice2ShapeCopy as ShapeCopy

View File

@ -32,6 +32,7 @@ from lattice2Common import *
import lattice2CompoundExplorer as LCE
import lattice2Markers
import lattice2Executer
from lattice2ShapeCopy import shallowCopy
def getDefLatticeFaceColor():
@ -112,6 +113,21 @@ class LatticeFeature():
obj.Proxy = self
def assureProperty(self, selfobj, proptype, propname, defvalue, group, tooltip):
"""assureProperty(selfobj, proptype, propname, defvalue, group, tooltip): adds
a property if one is missing, and sets its value to default. Does nothing if property
already exists. Returns True if property was created, or False if not."""
if hasattr(selfobj, propname):
#todo: check type match
return False
selfobj.addProperty(proptype, propname, group, tooltip)
if defvalue is not None:
setattr(selfobj, propname, defvalue)
return True
def derivedInit(self, obj):
'''for overriding by derived classes'''
@ -141,17 +157,17 @@ class LatticeFeature():
obj.Placement = App.Placement()
if bExposing:
obj.Shape = marker.copy()
obj.Shape = shallowCopy(marker)
obj.Placement = plms[0]
else:
for plm in plms:
sh = marker.copy()
sh = shallowCopy(marker)
sh.Placement = plm
shapes.append(sh)
if len(shapes) == 0:
obj.Shape = lattice2Markers.getNullShapeShape(markerSize)
raise ValueError('Lattice object is null') #Feeding empty compounds to FreeCAD seems to cause rendering issues, otherwise it would have been a good idea to output nothing.
raise ValueError('Lattice object is null')
sh = Part.makeCompound(shapes)
obj.Shape = sh

View File

@ -35,6 +35,7 @@ import lattice2BaseFeature
import lattice2CompoundExplorer as LCE
import lattice2Executer
from lattice2PopulateCopies import DereferenceArray
import lattice2ShapeCopy as ShapeCopy
# -------------------------- document object --------------------------------------------------
@ -63,9 +64,17 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyLink","PlacementsTo","Lattice PopulateChildren", "Placement or array of placements, containing target locations.")
obj.addProperty("App::PropertyLink","PlacementsFrom", "Lattice PopulateChildren","Placement or array of placements to be treated as origins for PlacementsTo.")
self.initNewProperties(obj)
def initNewProperties(self, obj):
# properties that can be missing on objects made with earlier version of Lattice2
if self.assureProperty(obj, "App::PropertyEnumeration","Copying", ShapeCopy.copy_types, "Lattice PopulateChildren", "Sets, what method to use for copying shapes."):
self.Copying = ShapeCopy.copy_types[0]
def derivedExecute(self,obj):
self.initNewProperties(obj)
outputIsLattice = lattice2BaseFeature.isObjectLattice(obj.Object)
if not lattice2BaseFeature.isObjectLattice(obj.Object):
@ -85,12 +94,12 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
# Precompute referencing
placements = DereferenceArray(obj, placements, obj.PlacementsFrom, obj.Referencing)
# initialize output containers and loop variables
outputShapes = [] #output list of shapes
outputPlms = [] #list of placements
iChild = 0
numChildren = len(objectPlms) if outputIsLattice else len(objectShapes)
copy_method_index = ShapeCopy.getCopyTypeIndex(obj.Copying)
# the essence
for iPlm in range(len(placements)):
@ -106,8 +115,8 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
objectPlm = objectPlms[iChild]
outputPlms.append(plm.multiply(objectPlm))
else:
outputShape = objectShapes[iChild].copy()
outputShape.Placement = plm.multiply(outputShape.Placement)
outputShape = ShapeCopy.copyShape(objectShapes[iChild], copy_method_index, plm)
# outputShape.Placement = plm.multiply(outputShape.Placement) #now done by shape copy routine
outputShapes.append(outputShape)
iChild += 1

View File

@ -34,6 +34,7 @@ from lattice2Common import *
import lattice2BaseFeature
import lattice2CompoundExplorer as LCE
import lattice2Executer
import lattice2ShapeCopy as ShapeCopy
# ---------------------------shared code--------------------------------------
def DereferenceArray(obj,placements, lnkFrom, refmode):
@ -100,6 +101,9 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
obj.addProperty("App::PropertyEnumeration", propname, "Lattice PopulateCopies","In case single object copy is made, this property controls, if it's packed into compoud or not.")
setattr(obj,propname,["(autosettle)","always", "only if many"])
setattr(obj,propname,"always") # this is to match the old behavior. This is not the default setting for new features.
if self.assureProperty(obj, "App::PropertyEnumeration","Copying", ShapeCopy.copy_types, "Lattice PopulateChildren", "Sets, what method to use for copying shapes."):
self.Copying = ShapeCopy.copy_types[0]
def derivedExecute(self,obj):
self.assureProperties(obj)
@ -119,6 +123,8 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
# initialize output containers and loop variables
outputShapes = [] #output list of shapes
outputPlms = [] #list of placements
copy_method_index = ShapeCopy.getCopyTypeIndex(obj.Copying)
# the essence
for plm in placements:
@ -127,8 +133,8 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
for objectPlm in objectPlms:
outputPlms.append(plm.multiply(objectPlm))
else:
outputShape = objectShape.copy()
outputShape.Placement = plm.multiply(outputShape.Placement)
outputShape = ShapeCopy.copyShape(objectShape, copy_method_index, plm)
#outputShape.Placement = plm.multiply(outputShape.Placement) # now handled by copyShape
outputShapes.append(outputShape)
if outputIsLattice:
@ -144,8 +150,7 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
#now, set the result shape
if len(outputShapes) == 1 and obj.OutputCompounding == "only if many":
sh = outputShapes[0]
sh.transformShape(sh.Placement.toMatrix(),True) #True = make copy
sh.Placement = App.Placement()
sh = ShapeCopy.transformCopy(sh)
obj.Shape = sh
else:
obj.Shape = Part.makeCompound(outputShapes)

87
lattice2ShapeCopy.py Normal file
View File

@ -0,0 +1,87 @@
#***************************************************************************
#* *
#* 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
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."""
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:
ret.Placement = extra_placement.multiply(ret.Placement)
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."""
ret = shape.copy()
if extra_placement is not None:
ret.Placement = extra_placement.multiply(ret.Placement)
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)."""
if extra_placement is None:
extra_placement = FreeCAD.Placement()
ret = shape.copy()
ret.transformShape(extra_placement.multiply(ret.Placement).toMatrix(), True)
ret.Placement = FreeCAD.Placement() #reset placement
return ret
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)