Merge branch 'shallow_copy'
This commit is contained in:
commit
3769ea460a
|
@ -6,3 +6,4 @@ import lattice2GeomUtils as GeomUtils
|
||||||
import lattice2InterpolatorUtil as InterpolatorUtil
|
import lattice2InterpolatorUtil as InterpolatorUtil
|
||||||
import lattice2Markers as Markers
|
import lattice2Markers as Markers
|
||||||
import lattice2ValueSeriesGenerator as ValueSeriesGenerator
|
import lattice2ValueSeriesGenerator as ValueSeriesGenerator
|
||||||
|
import lattice2ShapeCopy as ShapeCopy
|
|
@ -32,6 +32,7 @@ from lattice2Common import *
|
||||||
import lattice2CompoundExplorer as LCE
|
import lattice2CompoundExplorer as LCE
|
||||||
import lattice2Markers
|
import lattice2Markers
|
||||||
import lattice2Executer
|
import lattice2Executer
|
||||||
|
from lattice2ShapeCopy import shallowCopy
|
||||||
|
|
||||||
|
|
||||||
def getDefLatticeFaceColor():
|
def getDefLatticeFaceColor():
|
||||||
|
@ -112,6 +113,21 @@ class LatticeFeature():
|
||||||
|
|
||||||
obj.Proxy = self
|
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):
|
def derivedInit(self, obj):
|
||||||
'''for overriding by derived classes'''
|
'''for overriding by derived classes'''
|
||||||
|
@ -141,17 +157,17 @@ class LatticeFeature():
|
||||||
obj.Placement = App.Placement()
|
obj.Placement = App.Placement()
|
||||||
|
|
||||||
if bExposing:
|
if bExposing:
|
||||||
obj.Shape = marker.copy()
|
obj.Shape = shallowCopy(marker)
|
||||||
obj.Placement = plms[0]
|
obj.Placement = plms[0]
|
||||||
else:
|
else:
|
||||||
for plm in plms:
|
for plm in plms:
|
||||||
sh = marker.copy()
|
sh = shallowCopy(marker)
|
||||||
sh.Placement = plm
|
sh.Placement = plm
|
||||||
shapes.append(sh)
|
shapes.append(sh)
|
||||||
|
|
||||||
if len(shapes) == 0:
|
if len(shapes) == 0:
|
||||||
obj.Shape = lattice2Markers.getNullShapeShape(markerSize)
|
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)
|
sh = Part.makeCompound(shapes)
|
||||||
obj.Shape = sh
|
obj.Shape = sh
|
||||||
|
|
|
@ -35,6 +35,7 @@ import lattice2BaseFeature
|
||||||
import lattice2CompoundExplorer as LCE
|
import lattice2CompoundExplorer as LCE
|
||||||
import lattice2Executer
|
import lattice2Executer
|
||||||
from lattice2PopulateCopies import DereferenceArray
|
from lattice2PopulateCopies import DereferenceArray
|
||||||
|
import lattice2ShapeCopy as ShapeCopy
|
||||||
|
|
||||||
# -------------------------- document object --------------------------------------------------
|
# -------------------------- 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","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.")
|
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):
|
def derivedExecute(self,obj):
|
||||||
|
|
||||||
|
self.initNewProperties(obj)
|
||||||
|
|
||||||
outputIsLattice = lattice2BaseFeature.isObjectLattice(obj.Object)
|
outputIsLattice = lattice2BaseFeature.isObjectLattice(obj.Object)
|
||||||
|
|
||||||
if not lattice2BaseFeature.isObjectLattice(obj.Object):
|
if not lattice2BaseFeature.isObjectLattice(obj.Object):
|
||||||
|
@ -85,12 +94,12 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
|
||||||
# Precompute referencing
|
# Precompute referencing
|
||||||
placements = DereferenceArray(obj, placements, obj.PlacementsFrom, obj.Referencing)
|
placements = DereferenceArray(obj, placements, obj.PlacementsFrom, obj.Referencing)
|
||||||
|
|
||||||
|
|
||||||
# initialize output containers and loop variables
|
# initialize output containers and loop variables
|
||||||
outputShapes = [] #output list of shapes
|
outputShapes = [] #output list of shapes
|
||||||
outputPlms = [] #list of placements
|
outputPlms = [] #list of placements
|
||||||
iChild = 0
|
iChild = 0
|
||||||
numChildren = len(objectPlms) if outputIsLattice else len(objectShapes)
|
numChildren = len(objectPlms) if outputIsLattice else len(objectShapes)
|
||||||
|
copy_method_index = ShapeCopy.getCopyTypeIndex(obj.Copying)
|
||||||
|
|
||||||
# the essence
|
# the essence
|
||||||
for iPlm in range(len(placements)):
|
for iPlm in range(len(placements)):
|
||||||
|
@ -106,8 +115,8 @@ class LatticePopulateChildren(lattice2BaseFeature.LatticeFeature):
|
||||||
objectPlm = objectPlms[iChild]
|
objectPlm = objectPlms[iChild]
|
||||||
outputPlms.append(plm.multiply(objectPlm))
|
outputPlms.append(plm.multiply(objectPlm))
|
||||||
else:
|
else:
|
||||||
outputShape = objectShapes[iChild].copy()
|
outputShape = ShapeCopy.copyShape(objectShapes[iChild], copy_method_index, plm)
|
||||||
outputShape.Placement = plm.multiply(outputShape.Placement)
|
# outputShape.Placement = plm.multiply(outputShape.Placement) #now done by shape copy routine
|
||||||
outputShapes.append(outputShape)
|
outputShapes.append(outputShape)
|
||||||
|
|
||||||
iChild += 1
|
iChild += 1
|
||||||
|
|
|
@ -34,6 +34,7 @@ from lattice2Common import *
|
||||||
import lattice2BaseFeature
|
import lattice2BaseFeature
|
||||||
import lattice2CompoundExplorer as LCE
|
import lattice2CompoundExplorer as LCE
|
||||||
import lattice2Executer
|
import lattice2Executer
|
||||||
|
import lattice2ShapeCopy as ShapeCopy
|
||||||
|
|
||||||
# ---------------------------shared code--------------------------------------
|
# ---------------------------shared code--------------------------------------
|
||||||
def DereferenceArray(obj,placements, lnkFrom, refmode):
|
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.")
|
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,["(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.
|
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):
|
def derivedExecute(self,obj):
|
||||||
self.assureProperties(obj)
|
self.assureProperties(obj)
|
||||||
|
@ -119,6 +123,8 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
|
||||||
# initialize output containers and loop variables
|
# initialize output containers and loop variables
|
||||||
outputShapes = [] #output list of shapes
|
outputShapes = [] #output list of shapes
|
||||||
outputPlms = [] #list of placements
|
outputPlms = [] #list of placements
|
||||||
|
copy_method_index = ShapeCopy.getCopyTypeIndex(obj.Copying)
|
||||||
|
|
||||||
|
|
||||||
# the essence
|
# the essence
|
||||||
for plm in placements:
|
for plm in placements:
|
||||||
|
@ -127,8 +133,8 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
|
||||||
for objectPlm in objectPlms:
|
for objectPlm in objectPlms:
|
||||||
outputPlms.append(plm.multiply(objectPlm))
|
outputPlms.append(plm.multiply(objectPlm))
|
||||||
else:
|
else:
|
||||||
outputShape = objectShape.copy()
|
outputShape = ShapeCopy.copyShape(objectShape, copy_method_index, plm)
|
||||||
outputShape.Placement = plm.multiply(outputShape.Placement)
|
#outputShape.Placement = plm.multiply(outputShape.Placement) # now handled by copyShape
|
||||||
outputShapes.append(outputShape)
|
outputShapes.append(outputShape)
|
||||||
|
|
||||||
if outputIsLattice:
|
if outputIsLattice:
|
||||||
|
@ -144,8 +150,7 @@ class LatticePopulateCopies(lattice2BaseFeature.LatticeFeature):
|
||||||
#now, set the result shape
|
#now, set the result shape
|
||||||
if len(outputShapes) == 1 and obj.OutputCompounding == "only if many":
|
if len(outputShapes) == 1 and obj.OutputCompounding == "only if many":
|
||||||
sh = outputShapes[0]
|
sh = outputShapes[0]
|
||||||
sh.transformShape(sh.Placement.toMatrix(),True) #True = make copy
|
sh = ShapeCopy.transformCopy(sh)
|
||||||
sh.Placement = App.Placement()
|
|
||||||
obj.Shape = sh
|
obj.Shape = sh
|
||||||
else:
|
else:
|
||||||
obj.Shape = Part.makeCompound(outputShapes)
|
obj.Shape = Part.makeCompound(outputShapes)
|
||||||
|
|
87
lattice2ShapeCopy.py
Normal file
87
lattice2ShapeCopy.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user