From 6c620b130f739580a30ad6e97a68696e3a514d40 Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Thu, 16 Aug 2018 02:43:02 +0300 Subject: [PATCH] ReferencePlacement: show on screen initial implementation. to be improved... --- Lattice2CodeModules.py | 3 +- lattice2BaseFeature.py | 50 +++++++- lattice2CoinGlue.py | 49 ++++++++ lattice2Markers.py | 37 +++++- shapes/paperplane-orimarker-refplm.FCStd | Bin 0 -> 4044 bytes shapes/paperplane-orimarker-refplm.iv | 149 +++++++++++++++++++++++ 6 files changed, 277 insertions(+), 11 deletions(-) create mode 100644 lattice2CoinGlue.py create mode 100644 shapes/paperplane-orimarker-refplm.FCStd create mode 100644 shapes/paperplane-orimarker-refplm.iv diff --git a/Lattice2CodeModules.py b/Lattice2CodeModules.py index b5007d7..25ea80b 100644 --- a/Lattice2CodeModules.py +++ b/Lattice2CodeModules.py @@ -8,4 +8,5 @@ import lattice2Markers as Markers import lattice2ValueSeriesGenerator as ValueSeriesGenerator import lattice2ShapeCopy as ShapeCopy import lattice2Subsequencer as Subsequencer -import lattice2Utils as Utils \ No newline at end of file +import lattice2Utils as Utils +import lattice2CoinGlue as CoinGlue \ No newline at end of file diff --git a/lattice2BaseFeature.py b/lattice2BaseFeature.py index f3ff1f9..f7261af 100644 --- a/lattice2BaseFeature.py +++ b/lattice2BaseFeature.py @@ -33,6 +33,7 @@ import lattice2CompoundExplorer as LCE import lattice2Markers import lattice2Executer from lattice2ShapeCopy import shallowCopy +import lattice2CoinGlue as CoinGlue def getDefLatticeFaceColor(): @@ -130,12 +131,12 @@ class LatticeFeature(object): obj.Proxy = self - def assureProperty(self, selfobj, proptype, propname, defvalue, group, tooltip): + def assureProperty(self, selfobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False): """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.""" - return assureProperty(selfobj, proptype, propname, defvalue, group, tooltip) + return assureProperty(selfobj, proptype, propname, defvalue, group, tooltip, readonly, hidden) def setReferencePlm(self, selfobj, refplm): """setReferencePlm(selfobj, refplm): sets reference placement, in internal CS. If refplm is None, the property is removed.""" @@ -154,6 +155,13 @@ class LatticeFeature(object): ) selfobj.ReferencePlacement = refplm + def getReferencePlm(self, selfobj): + """getReferencePlm(self, selfobj): Returns reference placement in internal CS, or None.""" + if hasattr(selfobj, 'ReferencePlacement'): + return selfobj.ReferencePlacement + else: + return None + def derivedInit(self, obj): '''for overriding by derived classes''' pass @@ -172,6 +180,8 @@ class LatticeFeature(object): if markerSize < DistConfusion: markerSize = getMarkerSizeEstimate(plms) marker = lattice2Markers.getPlacementMarker(scale= markerSize, markerID= obj.MarkerShape) + self.assureProperty(obj, 'App::PropertyLength', 'MarkerSizeActual', markerSize, "Lattice", "Size of placement markers of this array", hidden= True) + obj.MarkerSizeActual = markerSize bExposing = False if obj.ExposePlacement: @@ -316,6 +326,27 @@ class ViewProviderLatticeFeature(object): def attach(self, vobj): self.ViewObject = vobj self.Object = vobj.Object + self.refplm_node, self.refplm_tr, self.refplm_sh = None, None, None + self.makeRefplmVisual(vobj) + from pivy import coin + self.modenode = next((node for node in vobj.RootNode.getChildren() if node.isOfType(coin.SoSwitch.getClassTypeId()))) + self.modenode_refplm = None + + def makeRefplmVisual(self, vobj): + import pivy + from pivy import coin + refplm = self.Object.Proxy.getReferencePlm(self.Object) + if refplm is not None: + if not hasattr(self.Object, 'MarkerSizeActual'): return + if self.refplm_node is None: + self.refplm_node, self.refplm_tr, self.refplm_sh = lattice2Markers.getRefPlmMarker(self.Object.MarkerShape) + vobj.RootNode.addChild(self.refplm_node) + self.modenode_refplm = next((node for node in self.refplm_sh.getChildren() if node.isOfType(coin.SoSwitch.getClassTypeId()))) + CoinGlue.cointransform(refplm, float(self.Object.MarkerSizeActual), self.refplm_tr) + else: + if hasattr(self, 'refplm_node') and self.refplm_node is not None: + vobj.RootNode.removeChild(self.refplm_node) + self.refplm_node, self.refplm_tr, self.refplm_sh = None, None, None def __getstate__(self): return None @@ -342,10 +373,19 @@ class ViewProviderLatticeFeature(object): # catch all exceptions, because we don't want to prevent deletion if something goes wrong FreeCAD.Console.PrintError("Error in onDelete: " + str(err)) return True + + def updateData(self, obj, prop): + if prop == 'ReferencePlacement' or prop == 'MarkerSizeActual': + self.makeRefplmVisual(obj.ViewObject) + + def onChanged(self, vobj, prop): + if prop == 'Visibility': + self.modenode_refplm.whichChild.setValue(0 if vobj.Visibility == True else -1) + -def assureProperty(docobj, proptype, propname, defvalue, group, tooltip): - """assureProperty(docobj, proptype, propname, defvalue, group, tooltip): adds +def assureProperty(docobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False): + """assureProperty(docobj, proptype, propname, defvalue, group, tooltip, readonly = False, hidden = False): 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.""" @@ -353,7 +393,7 @@ def assureProperty(docobj, proptype, propname, defvalue, group, tooltip): #todo: check type match return False - docobj.addProperty(proptype, propname, group, tooltip) + docobj.addProperty(proptype, propname, group, tooltip, 0, readonly, hidden) if defvalue is not None: setattr(docobj, propname, defvalue) return True diff --git a/lattice2CoinGlue.py b/lattice2CoinGlue.py new file mode 100644 index 0000000..09ef20c --- /dev/null +++ b/lattice2CoinGlue.py @@ -0,0 +1,49 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2018 - Victor Titov (DeepSOIC) * +#* * +#* * +#* 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__="CoinGlue module of FreeCAD add-on Lattice2" +__author__ = "DeepSOIC" +__url__ = "" +__doc__ = "Glue and conversion routines between coin and freecad" + +def cointransform(placement, scale = 1.0, modifyme = None): + """cointransform(placement, scale = 1.0, modifyme = None): creates/updates SoTransform node from FreeCAD.Placement. + modifyme: the existing node to be modified. + Returns: SoTransform node (new if modifyme is None else modifyme)""" + + from pivy import coin + tr = coin.SoTransform() if modifyme is None else modifyme + tr.scaleFactor.setValue(scale,scale,scale) + tr.translation.setValue(*tuple(placement.Base)) + tr.rotation.setValue(*placement.Rotation.Q) + return tr + +def readNodeFromFile(fullpath): + """readNodeFromFile(fullpath): reads a file. Returns SoSeparator node, containing the read out stuff.""" + from pivy import coin + i = coin.SoInput() + if not i.openFile(fullpath): raise ValueError("Failed to open file: {fn}".format(fn= fullpath)) + import pivy + sep = pivy.SoDB.readAll(i) + i.closeFile() + return sep diff --git a/lattice2Markers.py b/lattice2Markers.py index 305cce5..e9b03fe 100644 --- a/lattice2Markers.py +++ b/lattice2Markers.py @@ -21,15 +21,19 @@ #* * #*************************************************************************** -import Part, os +import Part +import os + +import lattice2CoinGlue as CoinGlue __title__="latticeMarkers module for FreeCAD" __author__ = "DeepSOIC" __url__ = "" __doc__ = "Module for loading marker shapes for Lattice workbench" -_nullShapeShape = 0 +_nullShapeShape = None _ShapeDict = {} +_NodeDict = {} def getShapePath(shapeName): """ @@ -44,7 +48,7 @@ def getNullShapeShape(scale = 1.0): #read shape from file, if not done this before global _nullShapeShape - if not _nullShapeShape: + if _nullShapeShape is None: _nullShapeShape = Part.Shape() f = open(getShapePath("empty-shape.brep")) _nullShapeShape.importBrep(f) @@ -73,8 +77,7 @@ def loadShape(shapeID): FreeCAD.Console.PrintError('Failed to load standard shape "'+shapeID+'". \n' + str(err) + '\n') sh = Part.Point() #Create at least something! _ShapeDict[shapeID] = sh - return sh - + return sh def getPlacementMarker(scale = 1.0, markerID = None): '''getPlacementMarker(scale = 1.0, markerID = None): returns a placement marker shape. @@ -87,3 +90,27 @@ def getPlacementMarker(scale = 1.0, markerID = None): sh = sh.copy() sh.scale(scale) return sh + +def loadNode(shapeID): + global _NodeDict + nd = _NodeDict.get(shapeID) + if nd is None: + nd = CoinGlue.readNodeFromFile(getShapePath(shapeID + '.iv')) + _NodeDict[shapeID] = nd + nd.ref() # not sure if needed, but won't hurt. + return nd + +def getRefPlmMarker(markerID, placement = None, scale = 1.0): + '''getRefPlmMarker(markerID, placement = None, scale = 1.0): returns a coin placement marker shape, as SoSeparator (+ transform node + shape node). + The shape is scaled according to "scale" argument. + markerID sets the marker file name.''' + sh = loadNode(markerID + '-refplm') + from pivy import coin + sep = coin.SoSeparator() + tr = coin.SoTransform() + if placement is not None: + CoinGlue.cointransform(placement, scale, tr) + sep.addChild(tr) + sep.addChild(sh) + return (sep, tr, sh) + diff --git a/shapes/paperplane-orimarker-refplm.FCStd b/shapes/paperplane-orimarker-refplm.FCStd new file mode 100644 index 0000000000000000000000000000000000000000..cb86ce8fd339ec671582a75dd5d95c5aff20f35c GIT binary patch literal 4044 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 C$PbnP literal 0 HcmV?d00001 diff --git a/shapes/paperplane-orimarker-refplm.iv b/shapes/paperplane-orimarker-refplm.iv new file mode 100644 index 0000000..109553e --- /dev/null +++ b/shapes/paperplane-orimarker-refplm.iv @@ -0,0 +1,149 @@ +#Inventor V2.1 ascii + +PickStyle { + style UNPICKABLE +} + +Coordinate3 { + point [ 2.4286127e-017 2.3747374e-017 0, + 1 0 0, + -0.28144613 -0.48747897 0, + 2.4286127e-017 2.3747374e-017 0, + -0.28144613 0.48747897 0, + 1 0 0, + 2.4286127e-017 2.3747374e-017 0, + 1 0 0, + 0 -6.3415941e-017 -0.28560001, + 2.4286127e-017 2.3747374e-017 0, + 1 0 0, + -0.28144613 -0.48747897 0, + -0.28144613 0.48747897 0, + 0 -6.3415941e-017 -0.28560001 ] +} + +Switch { + whichChild 0 + + Separator { + + DEF myLines Separator { + + MaterialBinding { + value OVERALL + + } + Material { + ambientColor 0.2 0.2 0.2 + diffuseColor 0.33333334 0.65490198 0.87058824 + specularColor 0 0 0 + emissiveColor 0 0 0 + shininess 1 + transparency 0 + + } + DrawStyle { + style LINES + lineWidth 2 + linePattern 0xffff + + } + SoBrepEdgeSet { + fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ] + coordIndex [ 0, 1, -1, 1, 2, -1, 2, 0, + -1, 3, 4, -1, 4, 5, -1, 8, + 6, -1, 7, 8, -1 ] + highlightIndex -1 + selectionIndex -1 + + } + } + PolygonOffset { + + } + DEF myFaces Separator { + + ShapeHints { + vertexOrdering UNKNOWN_ORDERING + shapeType UNKNOWN_SHAPE_TYPE + + } + MaterialBinding { + value OVERALL + + } + Material { + ambientColor 0.2 0.2 0.2 + diffuseColor 0 0.66666669 1 + specularColor 0 0 0 + emissiveColor 0 0 0 + shininess 0.2 + transparency 0.5 + + } + DrawStyle { + style FILLED + + } + Normal { + vector [ 0 0 1, + 0 0 1, + 0 0 1, + 0 0 1, + 0 0 1, + 0 0 1, + 0 -1 2.220446e-016, + 0 -1 2.220446e-016, + 0 -1 2.220446e-016 ] + + } + NormalBinding { + value PER_VERTEX_INDEXED + + } + SoBrepFaceSet { + fields [ SFNode vertexProperty, MFInt32 coordIndex, MFInt32 materialIndex, MFInt32 normalIndex, MFInt32 textureCoordIndex, MFInt32 partIndex, SFInt32 highlightIndex, MFInt32 selectionIndex ] + coordIndex [ 1, 0, 2, -1, 5, 4, 3, -1, + 7, 6, 8, -1 ] + partIndex [ 1, 1, 1 ] + highlightIndex -1 + selectionIndex -1 + + } + } + DEF myPoints Separator { + + MaterialBinding { + value OVERALL + + } + Material { + ambientColor 0.2 0.2 0.2 + diffuseColor 0.25490198 0.67450982 0.89803922 + specularColor 0 0 0 + emissiveColor 0 0 0 + shininess 1 + transparency 0 + + } + DrawStyle { + style POINTS + pointSize 2 + + } + SoBrepPointSet { + fields [ SFNode vertexProperty, SFInt32 startIndex, SFInt32 numPoints, SFInt32 highlightIndex, MFInt32 selectionIndex ] + startIndex 9 + highlightIndex -1 + selectionIndex [ 9, 10, 11, 12, 13 ] + + } + } + } + USE myFaces + Separator { + + USE myLines + USE myPoints + } + USE myPoints +}