FEM: add tool clipping plane tools

This commit is contained in:
Bernd Hahnebach
2018-06-05 22:29:18 +02:00
committed by wmayer
parent c3e64d2861
commit 7d7a02e00a
6 changed files with 472 additions and 2 deletions

View File

@@ -15,6 +15,8 @@
<file>icons/fem-cfd-analysis.svg</file>
<file>icons/fem-clip.svg</file>
<file>icons/fem-clip-scalar.svg</file>
<file>icons/fem-clipping-plane-add.svg</file>
<file>icons/fem-clipping-plane-remove-all.svg</file>
<file>icons/fem-constraint-bearing.svg</file>
<file>icons/fem-constraint-contact.svg</file>
<file>icons/fem-constraint-displacement.svg</file>

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r15371"
width="64"
height="64"
sodipodi:docname="fem-clipping-plane.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>[Alexander Gryson]</dc:title>
</cc:Agent>
</dc:creator>
<dc:title>fem-clip</dc:title>
<dc:date>2017-03-11</dc:date>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1353"
id="namedview4"
showgrid="true"
inkscape:zoom="9.8333332"
inkscape:cx="32.250885"
inkscape:cy="36.13053"
inkscape:window-x="0"
inkscape:window-y="58"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid2987"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1"
spacingy="1"
originx="0"
originy="0" />
</sodipodi:namedview>
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 51,45 8,2"
id="path3845"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 50.81276,44.789004 8,2"
id="path3845-5"
inkscape:connector-curvature="0" />
<g
id="g3834"
transform="translate(-80,0)">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3808"
d="M 104,58 90,13 83,11 83,49 z"
style="fill:#0066ff;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3810"
d="m 83,11 26,-8 8,1 -27,9 z"
style="fill:#0066ff;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3812"
d="M 117,4 131,45 104,56 90,13 z"
style="fill:#0066ff;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3814"
d="M 85,13.712363 85,47.74159 101.46741,54.557296 88.19775,14.53259 z"
style="fill:none;stroke:#8ae234;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3824"
d="m 92.26271,14.491525 13.38136,38.70339 23.14407,-9.483051 -13.43221,-37.194915 z"
style="fill:#0066ff;stroke:#73d216;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 12,14 31,19 59,11 37,6"
id="path2989"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 24,56 7,3 0,-40"
id="path2991"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 31,19 31,59 59,47 59,11 z"
id="path2993"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 12,14 31,19 59,11 37,6"
id="path2989-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 24,56 7,3 0,-40"
id="path2991-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 31,19 31,59 59,47 59,11 z"
id="path2993-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r15371"
width="64"
height="64"
sodipodi:docname="fem-clipping-plane-remove-all.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>[Alexander Gryson]</dc:title>
</cc:Agent>
</dc:creator>
<dc:title>fem-clip</dc:title>
<dc:date>2017-03-11</dc:date>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<linearGradient
id="linearGradient4504"
osb:paint="solid">
<stop
style="stop-color:#ff0000;stop-opacity:1;"
offset="0"
id="stop4502" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4504"
id="linearGradient4506"
x1="3.6401905"
y1="31.5"
x2="59.359809"
y2="31.5"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1353"
id="namedview4"
showgrid="true"
inkscape:zoom="9.8333332"
inkscape:cx="-5.74213"
inkscape:cy="36.187886"
inkscape:window-x="0"
inkscape:window-y="58"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid2987"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="1"
spacingy="1"
originx="0"
originy="0" />
</sodipodi:namedview>
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 51,45 8,2"
id="path3845"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 50.81276,44.789004 8,2"
id="path3845-5"
inkscape:connector-curvature="0" />
<g
id="g3834"
transform="translate(-80,0)">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3808"
d="M 104,58 90,13 83,11 83,49 z"
style="fill:#0066ff;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3810"
d="m 83,11 26,-8 8,1 -27,9 z"
style="fill:#0066ff;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3812"
d="M 117,4 131,45 104,56 90,13 z"
style="fill:#0066ff;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3814"
d="M 85,13.712363 85,47.74159 101.46741,54.557296 88.19775,14.53259 z"
style="fill:none;stroke:#8ae234;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3824"
d="m 92.26271,14.491525 13.38136,38.70339 23.14407,-9.483051 -13.43221,-37.194915 z"
style="fill:#0066ff;stroke:#73d216;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 12,14 31,19 59,11 37,6"
id="path2989"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 24,56 7,3 0,-40"
id="path2991"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#2e3436;stroke-width:6;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 31,19 31,59 59,47 59,11 z"
id="path2993"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 12,14 31,19 59,11 37,6"
id="path2989-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 24,56 7,3 0,-40"
id="path2991-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#d3d7cf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 31,19 31,59 59,47 59,11 z"
id="path2993-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 3,3 58,60"
id="path23"
inkscape:connector-curvature="0" />
<path
style="fill:url(#linearGradient4506);fill-rule:evenodd;stroke:#ff0000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 59,3 4,60"
id="path25"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -137,7 +137,6 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
results->setCommand("Results");
*results << "FEM_ResultsPurge"
<< "FEM_ResultShow";
#ifdef FC_USE_VTK
*results << "Separator"
<< "FEM_PostApplyChanges"
@@ -154,6 +153,11 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "FEM_PostCreateFunctions";
#endif
Gui::ToolBarItem* utils = new Gui::ToolBarItem(root);
utils->setCommand("Results");
*utils << "FEM_ClippingPlaneAdd"
<< "FEM_ClippingPlaneRemoveAll";
return root;
}
@@ -258,7 +262,6 @@ Gui::MenuItem* Workbench::setupMenuBar() const
results->setCommand("&Results");
*results << "FEM_ResultsPurge"
<< "FEM_ResultShow";
#ifdef FC_USE_VTK
*results << "Separator"
<< "FEM_PostApplyChanges"
@@ -275,5 +278,11 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "FEM_PostCreateFunctions";
#endif
Gui::MenuItem* utils = new Gui::MenuItem;
root->insertItem(item, utils);
utils->setCommand("Utilities");
*utils << "FEM_ClippingPlaneAdd"
<< "FEM_ClippingPlaneRemoveAll";
return root;
}

View File

@@ -52,6 +52,60 @@ class _CommandFemAnalysis(CommandManager):
FreeCAD.ActiveDocument.recompute()
class _CommandFemClippingPlaneAdd(CommandManager):
"The FEM_ClippingPlaneAdd command definition"
def __init__(self):
super(_CommandFemClippingPlaneAdd, self).__init__()
self.resources = {'Pixmap': 'fem-clipping-plane-add',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Clipping Plane", "Clipping plane on face"),
# 'Accel': "Z, Z",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Clipping Plane", "Add a clipping plane on a selected face")}
self.is_active = 'with_document'
def Activated(self):
from femtools import femutils
overalboundbox = femutils.getBoundBoxOfAllDocumentShapes(FreeCAD.ActiveDocument)
# print(overalboundbox)
min_bb_length = (min(set([overalboundbox.XLength, overalboundbox.YLength, overalboundbox.ZLength])))
dbox = min_bb_length * 0.2
aFace = femutils.getSelectedFace(FreeCADGui.Selection.getSelectionEx())
if aFace:
f_CoM = aFace.CenterOfMass
f_uvCoM = aFace.Surface.parameter(f_CoM) # u,v at CoM for normalAt calculation
f_normal = aFace.normalAt(f_uvCoM[0], f_uvCoM[1])
else:
f_CoM = FreeCAD.Vector(0, 0, 0)
f_normal = FreeCAD.Vector(0, 0, 1)
from pivy import coin
coin_normal_vector = coin.SbVec3f(-f_normal.x, -f_normal.y, -f_normal.z)
coin_bound_box = coin.SbBox3f(f_CoM.x - dbox, f_CoM.y - dbox, f_CoM.z - dbox * 0.15, f_CoM.x + dbox, f_CoM.y + dbox, f_CoM.z + dbox * 0.15)
clip_plane = coin.SoClipPlaneManip()
clip_plane.setValue(coin_bound_box, coin_normal_vector, 1)
FreeCADGui.ActiveDocument.ActiveView.getSceneGraph().insertChild(clip_plane, 1)
class _CommandFemClippingPlaneRemoveAll(CommandManager):
"The FEM_ClippingPlaneemoveAll command definition"
def __init__(self):
super(_CommandFemClippingPlaneRemoveAll, self).__init__()
self.resources = {'Pixmap': 'fem-clipping-plane-remove-all',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Clipping Plane", "remove all clipping planes"),
# 'Accel': "Z, Z",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Clipping Plane", "remove all clipping planes")}
self.is_active = 'with_document'
def Activated(self):
line1 = 'for node in list(sg.getChildren()):\n'
line2 = ' if isinstance(node, coin.SoClipPlane):\n'
line3 = ' sg.removeChild(node)'
FreeCADGui.doCommand("from pivy import coin")
FreeCADGui.doCommand("sg = Gui.ActiveDocument.ActiveView.getSceneGraph()")
FreeCADGui.doCommand("nodes = sg.getChildren()")
FreeCADGui.doCommand(line1 + line2 + line3)
class _CommandFemConstraintBodyHeatSource(CommandManager):
"The FEM_ConstraintBodyHeatSource command definition"
def __init__(self):
@@ -773,6 +827,8 @@ class _CommandFemSolverZ88(CommandManager):
# the string in add command will be the page name on FreeCAD wiki
FreeCADGui.addCommand('FEM_Analysis', _CommandFemAnalysis())
FreeCADGui.addCommand('FEM_ClippingPlaneAdd', _CommandFemClippingPlaneAdd())
FreeCADGui.addCommand('FEM_ClippingPlaneRemoveAll', _CommandFemClippingPlaneRemoveAll())
FreeCADGui.addCommand('FEM_ConstraintBodyHeatSource', _CommandFemConstraintBodyHeatSource())
FreeCADGui.addCommand('FEM_ConstraintElectrostaticPotential', _CommandFemConstraintElectrostaticPotential())
FreeCADGui.addCommand('FEM_ConstraintFlowVelocity', _CommandFemConstraintFlowVelocity())

View File

@@ -27,6 +27,7 @@ __author__ = "Markus Hovorka, Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"
import FreeCAD
import FreeCAD as App
@@ -100,3 +101,37 @@ def isDerivedFrom(obj, t):
obj.Proxy.Type == t):
return True
return obj.isDerivedFrom(t)
def getBoundBoxOfAllDocumentShapes(doc):
overalboundbox = None
for o in doc.Objects:
if hasattr(o, 'Shape'):
try:
bb = o.Shape.BoundBox
except:
bb = None
if bb.isValid():
if not overalboundbox:
overalboundbox = bb
overalboundbox.add(bb)
return overalboundbox
def getSelectedFace(selectionex):
aFace = None
# print(selectionex)
if len(selectionex) != 1:
FreeCAD.Console.PrintMessage('no or more than one object selected')
else:
sel = selectionex[0]
if len(sel.SubObjects) != 1:
FreeCAD.Console.PrintMessage('more than one element selected')
else:
aFace = sel.SubObjects[0]
if aFace.ShapeType != 'Face':
FreeCAD.Console.PrintMessage('not a Face selected')
else:
FreeCAD.Console.PrintMessage(':-)')
return aFace
return aFace