From 651cd398c6990351b773caa34fc9bd86225f3b71 Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Sun, 25 Oct 2015 16:10:58 +0300 Subject: [PATCH] [big change] Use marker shape instead of points Because points lost placements when saving/restoring. --- latticeBaseFeature.py | 87 ++++++++++-- latticeCompose.py | 97 +++++++++----- latticeCompoundExplorer.py | 2 +- latticeMarkers.py | 29 ++++ latticePolarArray.py | 19 +-- shapes/tetra-orimarker.FCStd | Bin 0 -> 33927 bytes shapes/tetra-orimarker.brep | 249 +++++++++++++++++++++++++++++++++++ 7 files changed, 429 insertions(+), 54 deletions(-) create mode 100644 shapes/tetra-orimarker.FCStd create mode 100644 shapes/tetra-orimarker.brep diff --git a/latticeBaseFeature.py b/latticeBaseFeature.py index d309180..6a64228 100644 --- a/latticeBaseFeature.py +++ b/latticeBaseFeature.py @@ -25,11 +25,12 @@ __title__="Base feature module for lattice object of lattice workbench for FreeC __author__ = "DeepSOIC" __url__ = "" +import FreeCAD as App import Part -from pivy import coin from latticeCommon import * import latticeCompoundExplorer as LCE +import latticeMarkers def makeLatticeFeature(name, AppClass, icon, ViewClass = None): '''makeLatticeFeature(name, AppClass, ViewClass = None): makes a document object for a LatticeFeature-derived object.''' @@ -42,16 +43,47 @@ def makeLatticeFeature(name, AppClass, icon, ViewClass = None): vp.icon = icon return obj + +def isObjectLattice(documentObject): + '''isObjectLattice(documentObject): When operating on the object, it is to be treated as a lattice object. If False, treat as a regular shape.''' + ret = False + if hasattr(documentObject,"isLattice"): + if documentObject.isLattice == 'True': + ret = True + return ret + +def getMarkerSizeEstimate(ListOfPlacements): + '''getMarkerSizeEstimate(ListOfPlacements): computes the default marker size for the array of placements''' + if len(ListOfPlacements) == 0: + return 1.0 + pathLength = 0 + for i in range(1, len(ListOfPlacements)): + pathLength += (ListOfPlacements[i].Base - ListOfPlacements[i-1].Base).Length + sz = pathLength/len(ListOfPlacements)/2.0 + #FIXME: make hierarchy-aware + if sz < DistConfusion*10: + sz = 1.0 + return sz + + + class LatticeFeature(): "Base object for lattice objects (arrays of placements)" def __init__(self,obj): + # please, don't override. Override derivedInit instead. self.Type = "latticeFeature" prop = "NumElements" obj.addProperty("App::PropertyInteger",prop,"Info","Number of placements in the array") obj.setEditorMode(prop, 1) # set read-only + + obj.addProperty("App::PropertyLength","MarkerSize","Lattice","Size of placement markers (set to zero for automatic).") + + obj.addProperty("App::PropertyEnumeration","isLattice","Lattice","Sets whether this object should be treated as a lattice by further operations") + obj.isLattice = ['Auto','False','True'] + self.derivedInit(obj) obj.Proxy = self @@ -62,14 +94,53 @@ class LatticeFeature(): pass def execute(self,obj): - derivedExecute(self, obj) - obj.NumElements = LCE.CalculateNumberOfLeaves(obj.Shape) + # please, don't override. Override derivedExecute instead. + + plms = self.derivedExecute(obj) + + if plms is not None: + obj.NumElements = len(plms) + shapes = [] + markerSize = obj.MarkerSize + if markerSize < DistConfusion: + markerSize = getMarkerSizeEstimate(plms) + marker = latticeMarkers.getPlacementMarker(scale=markerSize) + #FIXME: make hierarchy-aware + for plm in plms: + sh = marker.copy() + sh.Placement = plm + shapes.append(sh) + + if len(shapes) == 0: + obj.Shape = markers.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. + + obj.Shape = Part.makeCompound(shapes) + + if obj.isLattice == 'Auto': + obj.isLattice = 'True' + + else: + # DerivedExecute didn't return anything. Thus we assume it + # has assigned the shape, and thus we don't do anything. + # Moreover, we assume that it is no longer a lattice object, so: + if obj.isLattice == 'Auto': + obj.isLattice = 'False' + obj.NumElements = len(obj.Shape.childShapes(False,False)) return - def derivedExecute(): - '''For overriding by derived class''' - pass + def derivedExecute(self,obj): + '''For overriding by derived class. If this returns a list of placements, + it's going to be used to build the shape. If returns None, it is assumed that + derivedExecute has already assigned the shape, and no further actions are needed.''' + return [] + + def verifyIntegrity(self,obj): + if self.__init__.__func__ is not LatticeFeature.__init__.__func__: + FreeCAD.Console.PrintError("__init__() of lattice object is overridden. Please don't! Fix it!\n") + if self.execute.__func__ is not LatticeFeature.execute.__func__: + FreeCAD.Console.PrintError("execute() of lattice object is overridden. Please don't! Fix it!\n") class ViewProviderLatticeFeature: @@ -78,10 +149,9 @@ class ViewProviderLatticeFeature: def __init__(self,vobj): vobj.Proxy = self # vobj.DisplayMode = "Markers" - vobj.PointSize = 4 - vobj.PointColor = (1.0, 0.7019608020782471, 0.0, 0.0) #orange def getIcon(self): + self.Object.Proxy.verifyIntegrity(self.Object) if hasattr(self, "icon"): if self.icon: return getIconPath(self.icon) @@ -111,6 +181,7 @@ class ViewProviderLatticeFeature: try: children = self.claimChildren() if children and len(children) > 0: + marker = latticeMarkers for child in children: child.ViewObject.show() except Exception as err: diff --git a/latticeCompose.py b/latticeCompose.py index 81304ea..97367de 100644 --- a/latticeCompose.py +++ b/latticeCompose.py @@ -68,8 +68,8 @@ class Compose(latticeBaseFeature.LatticeFeature): obj.ToolFlattenHierarchy = True - def execute(self,obj): - # Fill in (update read-only) properties that are driven by the mode. + def derivedExecute(self,obj): + # cache stuff base = obj.Base.Shape if base.ShapeType != 'Compound': base = Part.makeCompound([base]) @@ -87,45 +87,82 @@ class Compose(latticeBaseFeature.LatticeFeature): toolChildren = tool.childShapes() iBase = 0 - isMult = obj.Operation == 'MultiplyPlacements' # cache comparisons to speed them up + isMult = obj.Operation == 'MultiplyPlacements' # cache mode comparisons to speed them up isAvg = obj.Operation == 'AveragePlacements' isIgnore = obj.Operation == 'IgnoreBasePlacements' - isOvrride = obj.Operation == 'OverrideBasePlacements' - rst = [] + isOverride = obj.Operation == 'OverrideBasePlacements' + + #mode validity logic + if not latticeBaseFeature.isObjectLattice(obj.Tool): + FreeCAD.Console.PrintWarning(obj.Name+': Tool is not a lattice object. Results may be unexpected.\n') + outputIsLattice = latticeBaseFeature.isObjectLattice(obj.Base) + if isOverride and outputIsLattice: + FreeCAD.Console.PrintWarning(obj.Name+': Base is a lattice object. OverrideBasePlacements operation requires a generic compound as Base. So, the lattice is being treated as a generic compound.\n') + outputIsLattice = False + + # initialize output containers and loop variables + outputShapes = [] #output list of shapes + outputPlms = [] #list of placements bFirst = True plmMatcher = App.Placement() #extra placement, that aligns first tool member and first base member + + + # the essence for toolChild in toolChildren: - sh = baseChildren[iBase].copy() - if bFirst: - bFirst = False - if obj.BaseKeepPosOfFirst: - plmMatcher = toolChild.Placement.inverse() - toolPlm = plmMatcher.multiply(toolChild.Placement) - if isMult: - sh.Placement = toolPlm.multiply(sh.Placement) - elif isAvg: - plm1 = toolPlm - plm2 = sh.Placement - transl = plm1.Base*0.5 + plm2.Base*0.5 - a1,b1,c1,d1 = plm1.Rotation.Q - a2,b2,c2,d2 = plm2.Rotation.Q - rot = App.Rotation((a1+a2,b1+b2,c1+c2,d1+d2)) #no divide-by-two, because FreeCAD will normalize the quaternion automatically - sh.Placement = App.Placement(transl,rot) - elif isIgnore: - sh.Placement = toolPlm - elif isOverride: - sh.transformShape(toolPlm.inverse.multiply(sh.Placement)) - sh.Placement = toolPlm - rst.append(sh) - iBase += 1 + # early test for termination if iBase > len(baseChildren)-1: if obj.BaseLoopSequence: iBase = 0 else: + FreeCAD.Console.PrintWarning(obj.Name+': There are '+str(len(toolChildren)-len(baseChildren))+ + ' more placements in Tool than children in Base. Those placements'+ + ' were dropped.\n') break - - obj.Shape = Part.makeCompound(rst) + + #cache some stuff + basePlm = baseChildren[iBase].Placement + toolPlm = toolChild.Placement + + if not outputIsLattice: + outputShape = baseChildren[iBase].copy() + + #prepare alignment placement + if bFirst: + bFirst = False + if obj.BaseKeepPosOfFirst: + plmMatcher = toolPlm.inverse() + + #mode logic + if isMult: + outPlm = toolPlm.multiply(plmMatcher.multiply(basePlm)) + elif isAvg: + plm1 = toolPlm + plm2 = pltMatcher.multiply(basePlm) + transl = plm1.Base*0.5 + plm2.Base*0.5 + a1,b1,c1,d1 = plm1.Rotation.Q + a2,b2,c2,d2 = plm2.Rotation.Q + rot = App.Rotation((a1+a2,b1+b2,c1+c2,d1+d2)) #no divide-by-two, because FreeCAD will normalize the quaternion automatically + outPlm = App.Placement(transl,rot) + elif isIgnore: + outPlm = toolPlm + elif isOverride: + assert(not outputIsLattice) + outputShape.transformShape(toolPlm.inverse.multiply(plmMatcher.multiply(basePlm))) + outPlm = toolPlm + + if outputIsLattice: + outputPlms.append(outPlm) + else: + outputShape.Placement = outPlm + outputShapes.append(outputShape) + + iBase += 1 + + if outputIsLattice: + return outputPlms + else: + obj.Shape = Part.makeCompound(outputShapes) class ViewProviderCompose(latticeBaseFeature.ViewProviderLatticeFeature): diff --git a/latticeCompoundExplorer.py b/latticeCompoundExplorer.py index a84ac01..94b689c 100644 --- a/latticeCompoundExplorer.py +++ b/latticeCompoundExplorer.py @@ -144,7 +144,7 @@ def CalculateNumberOfLeaves(compound): return cnt def AllLeaves(compound): - 'AllLeaves(compound): Traverses the compound and collects all the leaves into a single list' + 'AllLeaves(compound): Traverses the compound and collects all the leaves into a single list. Returns list of shapes.' output = [] for (child, msg, it) in CompoundExplorer(compound): if msg == it.MSG_LEAF: diff --git a/latticeMarkers.py b/latticeMarkers.py index dfde102..7f2dc4a 100644 --- a/latticeMarkers.py +++ b/latticeMarkers.py @@ -29,6 +29,7 @@ __url__ = "" __doc__ = "Module for loading marker shapes for Lattice workbench" _nullShapeShape = 0 +_ShapeDict = {} def getShapePath(shapeName): """ @@ -56,3 +57,31 @@ def getNullShapeShape(scale = 1.0): ret.scale(scale) return ret + +def loadShape(shapeID): + global _ShapeDict + sh = _ShapeDict.get(shapeID) + if sh is None: + try: + sh = Part.Shape() + f = open(getShapePath(shapeID + '.brep')) + sh.importBrep(f) + f.close() + except Exception as err: + FreeCAD.Console.PrintError('Failed to load standard shape "'+shapeID+'". \n' + err.message + '\n') + sh = Part.Point() #Create at least something! + _ShapeDict[shapeID] = sh + return sh + + +def getPlacementMarker(scale = 1.0, markerID = None): + '''getPlacementMarker(scale = 1.0, markerID = None): returns a placement marker shape. + The shape is scaled according to "scale" argument. + markerID sets the marker file name. If omitted, default placement marker is returned.''' + if markerID is None: + markerID = 'tetra-orimarker' + sh = loadShape(markerID) + if scale != 1.0: + sh = sh.copy() + sh.scale(scale) + return sh diff --git a/latticePolarArray.py b/latticePolarArray.py index 8397f9d..a76694b 100644 --- a/latticePolarArray.py +++ b/latticePolarArray.py @@ -86,7 +86,7 @@ class PolarArray(latticeBaseFeature.LatticeFeature): obj.setEditorMode("AxisLinkIgnorePoint", 0 if obj.AxisLink else 1) - def execute(self,obj): + def derivedExecute(self,obj): # Fill in (update read-only) properties that are driven by the mode. self.updateReadOnlyness(obj) if obj.Mode == 'SpanN': @@ -151,27 +151,16 @@ class PolarArray(latticeBaseFeature.LatticeFeature): overallPlacement = App.Placement(obj.AxisPoint, rot_ini) # Make the array - rst = [] # Shapes for holding placements (each shape is a vertex with placement) + output = [] # list of placements for i in range(0, n): ang = startAng + step*i p = Part.Vertex() localrot = App.Rotation(App.Vector(0,0,1), ang) localtransl = localrot.multVec(App.Vector(radius,0,0)) localplm = App.Placement(localtransl, localrot) - p.Placement = overallPlacement.multiply(localplm) - rst.append(p) + output.append( overallPlacement.multiply(localplm) ) - # Make final compound (or empty-set marker) - if len(rst) == 0: - scale = 1.0 - if not obj.Base.Shape.isNull(): - scale = abs(obj.Radius) - if scale < DistConfusion * 100: - scale = 1.0 - obj.Shape = markers.getNullShapeShape(scale) - raise ValueError('Array output is null') #Feeding empty compounds to FreeCAD seems to cause rendering issues, otherwise it would have been a good idea to output nothing. - - obj.Shape = Part.makeCompound(rst) + return output else: raise ValueError("Spreadsheet mode not implemeted yet") diff --git a/shapes/tetra-orimarker.FCStd b/shapes/tetra-orimarker.FCStd new file mode 100644 index 0000000000000000000000000000000000000000..4ed8e4fff50f027f1cabdc447b0a564f4e9f4902 GIT binary patch literal 33927 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

g~vy!TI75 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ࢻICM$2Va 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 Y04?boz&DUUMC^@>1o?#s{yKB{f1|85VgLXD literal 0 HcmV?d00001 diff --git a/shapes/tetra-orimarker.brep b/shapes/tetra-orimarker.brep new file mode 100644 index 0000000..8682af4 --- /dev/null +++ b/shapes/tetra-orimarker.brep @@ -0,0 +1,249 @@ +DBRep_DrawableShape + +CASCADE Topology V1, (c) Matra-Datavision +Locations 15 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +1 + 0 0 -1 -0 + -1 0 0 -0 + 0 1 0 0 +2 4 1 3 1 0 +2 3 -1 4 -1 0 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +1 +-0.978231976089037 2.77555756156289e-017 0.207514339159822 0.043062200956938 +0.146734796413355 -0.707106781186547 0.691714463866075 0.14354066985646 +0.146734796413356 0.707106781186547 0.691714463866075 0.14354066985646 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +2 8 1 9 1 0 +2 9 -1 8 -1 0 +1 +0.978231976089037 2.77555756156289e-017 0.207514339159822 0.043062200956938 +0.146734796413355 0.707106781186547 -0.691714463866075 -0.14354066985646 +-0.146734796413356 0.707106781186547 0.691714463866075 0.14354066985646 +1 + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 +2 12 1 13 1 0 +2 13 -1 12 -1 0 +Curve2ds 0 +Curves 7 +1 0 0 0 1 0 0 +1 -0.29999999999998128 -4.2695787882546599e-015 0 1 1.4231929294183087e-014 0 +1 0.29999999999999999 0 0 -0.70710678118654524 0.70710678118654957 0 +1 2.2233792906188499e-017 0.30000000000000182 0 -0.70710678118651826 -0.70710678118657666 0 +1 0.044020438924006873 -0.21213203435596539 0 -0.9791402332302942 0.20318563844357879 0 +1 -0.04402043892400688 -0.21213203435596534 0 0.9791402332302942 0.20318563844357873 0 +1 -0.97823197608904322 1.214306433183765e-016 0 0.97914023323029442 0.20318563844357873 0 +Polygon3D 0 +PolygonOnTriangulations 14 +2 1 2 +p 0.00316666666666669 1 0 0.3 +2 2 4 +p 0.00316666666666669 1 0 0.3 +2 3 1 +p 0.00316666666666669 1 0 0.299999999999981 +2 1 2 +p 0.00316666666666669 1 0 0.299999999999981 +2 2 4 +p 0.00316666666666669 1 0 0.42426406871193 +2 1 3 +p 0.00316666666666669 1 0 0.42426406871193 +2 4 3 +p 0.00316666666666669 1 0 0.42426406871192 +2 2 3 +p 0.00316666666666669 1 0 0.42426406871192 +2 1 3 +p 0.00316666666666669 1 0 1.04403065089106 +2 3 1 +p 0.00316666666666669 1 0 1.04403065089106 +2 4 3 +p 0.00316666666666669 1 0 1.04403065089106 +2 1 2 +p 0.00316666666666669 1 0 1.04403065089106 +2 2 3 +p 0.00316666666666669 1 0 1.04403065089106 +2 1 2 +p 0.00316666666666669 1 0 1.04403065089106 +Surfaces 4 +1 0 0 0 1 0 -0 0 0 1 0 -1 0 +1 0 0 0 0 0 1 1 0 -0 -0 1 0 +1 0.41556347085957146 -0.087665479371065044 0.087665479371065141 -0.20751433915982237 0.6917144638660746 -0.69171446386607471 0 -0.70710678118654757 -0.70710678118654746 -0.978231976089037 -0.14673479641335552 0.14673479641335554 +1 0.41556347085957152 0.087665479371065058 0.087665479371065114 -0.20751433915982231 -0.69171446386607471 -0.69171446386607471 0 -0.70710678118654757 0.70710678118654757 -0.97823197608903711 0.14673479641335549 0.14673479641335549 +Triangulations 4 +4 2 1 4.2491376305591e-018 +0 0 0 -1.73472347597681e-018 -0.300000000000001 1.38777878078145e-017 1.73472347597681e-018 0.299999999999991 -2.13598435909256e-015 -1.73472347597681e-018 8.31933993028464e-018 0.300000000000002 0 0 1.38777878078145e-017 0.300000000000001 -2.13598435909256e-015 -0.299999999999991 0.300000000000002 0 4 2 1 4 1 3 +4 2 1 7.18933680268093e-016 +1.73472347597681e-018 0.299999999999991 -2.13598435909256e-015 0 0 0 1.00000000000001 -2.77555756156289e-017 -2.08166817117217e-017 -1.73472347597681e-018 -0.300000000000001 1.38777878078145e-017 1.73472347597681e-018 0.299999999999992 0 0 1.00000000000001 0 -1.73472347597681e-018 -0.300000000000001 3 1 2 3 2 4 +3 1 1 6.93889390390723e-017 +-1.73472347597681e-018 -0.300000000000001 1.38777878078145e-017 1.00000000000001 -2.77555756156289e-017 -2.08166817117217e-017 -1.73472347597681e-018 8.31933993028464e-018 0.300000000000002 0.212132034355965 0.424810761677399 8.32667268468867e-017 -0.59744165333565 -0.212132034355965 0.4248107616774 1 3 2 +3 1 1 2.692290834716e-015 +1.00000000000001 -2.77555756156289e-017 -2.08166817117217e-017 -1.73472347597681e-018 8.31933993028464e-018 0.300000000000002 1.73472347597681e-018 0.299999999999991 -2.13598435909256e-015 -2.77555756156289e-017 -0.59744165333565 0.212132034355966 0.4248107616774 -0.21213203435596 0.424810761677398 2 3 1 + +TShapes 23 +Ve +1e-007 +0 0 0 +0 0 + +0101101 +* +Ve +1.00000000839442e-007 +-1.73472347597681e-018 -0.300000000000001 1.38777878078145e-017 +0 0 + +0101101 +* +Ed + 1e-007 1 1 0 +1 1 0 0 0.3 +6 1 1 6 +6 2 2 6 +0 + +0101000 ++23 6 -22 6 * +Ve +1.00000010384143e-007 +1.73472347597681e-018 0.299999999999991 -2.13598435909256e-015 +0 0 + +0101101 +* +Ed + 1e-007 1 1 0 +1 2 0 0 0.299999999999981 +6 3 1 6 +6 4 2 6 +0 + +0101000 ++20 6 -23 6 * +Ve +1.00000000178043e-007 +-1.73472347597681e-018 8.31933993028464e-018 0.300000000000002 +0 0 + +0101101 +* +Ed + 1e-007 1 1 0 +1 3 0 0 0.42426406871193 +6 5 1 6 +6 6 3 6 +0 + +0101000 ++22 6 -18 6 * +Ed + 1e-007 1 1 0 +1 4 0 0 0.42426406871192 +6 7 1 6 +6 8 4 6 +0 + +0101000 ++18 6 -20 6 * +Wi + +0101000 +-21 5 -19 5 -17 5 -16 5 * +Fa +0 1e-007 1 3 +2 1 +0111000 ++15 0 * +Ve +1.00000000466544e-007 +1.00000000000001 -2.77555756156289e-017 -2.08166817117217e-017 +0 0 + +0101101 +* +Ed + 1e-007 1 1 0 +1 5 0 0 1.04403065089106 +6 9 2 11 +6 10 4 11 +0 + +0101000 ++20 11 -13 11 * +Ed + 1e-007 1 1 0 +1 6 0 0 1.04403065089106 +6 11 2 15 +6 12 3 15 +0 + +0101000 ++22 15 -13 15 * +Wi + +0101000 ++19 5 -12 10 +21 5 +11 14 * +Fa +0 1e-007 2 7 +2 2 +0111000 ++10 0 * +Ed + 1e-007 1 1 0 +1 7 0 0 1.04403065089106 +6 13 3 11 +6 14 4 11 +0 + +0101000 ++13 11 -18 11 * +Wi + +0101000 +-11 14 +17 5 -8 10 * +Fa +0 1e-007 3 13 +2 3 +0111000 ++7 0 * +Wi + +0101000 ++8 10 +12 10 +16 5 * +Fa +0 1e-007 4 9 +2 4 +0111000 ++5 0 * +Sh + +0101000 ++14 2 +9 2 +6 2 +4 2 * +So + +0100000 ++3 0 * +Co + +1100000 +-2 1 * + ++1 0 \ No newline at end of file