ReferencePlacement: show on screen

initial implementation. to be improved...
This commit is contained in:
DeepSOIC 2018-08-16 02:43:02 +03:00
parent 9449dd9352
commit 6c620b130f
6 changed files with 277 additions and 11 deletions

View File

@ -8,4 +8,5 @@ import lattice2Markers as Markers
import lattice2ValueSeriesGenerator as ValueSeriesGenerator
import lattice2ShapeCopy as ShapeCopy
import lattice2Subsequencer as Subsequencer
import lattice2Utils as Utils
import lattice2Utils as Utils
import lattice2CoinGlue as CoinGlue

View File

@ -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

49
lattice2CoinGlue.py Normal file
View File

@ -0,0 +1,49 @@
#***************************************************************************
#* *
#* Copyright (c) 2018 - 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__="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

View File

@ -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)

Binary file not shown.

View File

@ -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
}