~freecad-community/freecad-extras/lattice2

110 by DeepSOIC
V2: renaming .py files
1
#***************************************************************************
2
#*                                                                         *
3
#*   Copyright (c) 2015 - Victor Titov (DeepSOIC)                          *
4
#*                                               <vv.titov@gmail.com>      *  
5
#*                                                                         *
6
#*   This program is free software; you can redistribute it and/or modify  *
7
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
8
#*   as published by the Free Software Foundation; either version 2 of     *
9
#*   the License, or (at your option) any later version.                   *
10
#*   for detail see the LICENCE text file.                                 *
11
#*                                                                         *
12
#*   This program is distributed in the hope that it will be useful,       *
13
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
#*   GNU Library General Public License for more details.                  *
16
#*                                                                         *
17
#*   You should have received a copy of the GNU Library General Public     *
18
#*   License along with this program; if not, write to the Free Software   *
19
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
#*   USA                                                                   *
21
#*                                                                         *
22
#***************************************************************************
23
24
__title__="Command to inspect selected object compounding structure"
25
__author__ = "DeepSOIC"
26
__url__ = ""
27
28
import FreeCAD as App
29
import Part
30
114 by DeepSOIC
V2: renames inside files
31
from lattice2Common import *
32
import lattice2CompoundExplorer as LCE
33
import lattice2BaseFeature
110 by DeepSOIC
V2: renaming .py files
34
35
def shapeInfoString(shape):
36
    strMsg = shape.ShapeType 
37
    if shape.ShapeType == 'Vertex':
38
        strMsg += " ("+repr(list(shape.Point))+")"
39
    elif shape.ShapeType == 'Edge':
40
        strMsg += " ("+repr(shape.Curve)+")"
41
    elif shape.ShapeType == 'Wire':
42
        strMsg += " ("+str(len(shape.childShapes()))+" segments)"
43
    elif shape.ShapeType == 'Face':
44
        strMsg += " ("+repr(shape.Surface)+")"
45
    elif shape.ShapeType == 'Shell':
46
        strMsg += " ("+str(len(shape.childShapes()))+" faces)"
47
    elif shape.ShapeType == 'Solid':
48
        strMsg += " ("+str(len(shape.childShapes()))+" shells)"
49
    elif shape.ShapeType == 'CompSolid':
50
        strMsg += " ("+str(len(shape.childShapes()))+" solids)"
51
    elif shape.ShapeType == 'Compound':
52
        strMsg += " ("+str(len(shape.childShapes()))+" objects)"
53
    return strMsg
54
55
class _CommandInspect:
56
    "Command to inspect compounding structure"
57
        
58
    def __init__(self):
59
        pass
60
    
61
    def GetResources(self):
114 by DeepSOIC
V2: renames inside files
62
        return {'Pixmap'  : getIconPath("Lattice2_Inspect.svg"),
63
                'MenuText': QtCore.QT_TRANSLATE_NOOP("Lattice2_Inspect","Inspect selection") , # FIXME: not translation-friendly!
110 by DeepSOIC
V2: renaming .py files
64
                'Accel': "",
114 by DeepSOIC
V2: renames inside files
65
                'ToolTip': QtCore.QT_TRANSLATE_NOOP("Lattice2_Inspect","Lattice Inspect: display info on compounding structure of selected object.")}
110 by DeepSOIC
V2: renaming .py files
66
        
67
    def Activated(self):
68
        sel = FreeCADGui.Selection.getSelectionEx()[0]
116 by DeepSOIC
V2: more internal changes due to file renames
69
        isLattice = lattice2BaseFeature.isObjectLattice(sel.Object)
110 by DeepSOIC
V2: renaming .py files
70
        
71
        strStructure = []
72
        if not hasattr(sel.Object,"Shape"):
73
            strStructure = ["<object has no shape!>"]
211 by DeepSOIC
Inspect: clarify messages; fix silent failure on shapeless features
74
        else:
231 by DeepSOIC
Inspect: fix null shapes; limit number of lines displayed
75
            if sel.Object.Shape.isNull():
248 by DeepSOIC
Py3: fix syntax errors
76
                strStructure.append("<NULL SHAPE!>")
231 by DeepSOIC
Inspect: fix null shapes; limit number of lines displayed
77
            else:
78
                for (child, msg, it) in LCE.CompoundExplorer(sel.Object.Shape):
79
                    #child is a shape. 
80
                    #msg is int equal to one of three constants:
81
                    #    CompoundExplorer.MSG_LEAF  - child is a leaf (non-compound)
82
                    #    CompoundExplorer.MSG_DIVEDOWN  - child is a compound that is about to be traversed
83
                    #    CompoundExplorer.MSG_BUBBLEUP  - child is a compound that was just finished traversing        
84
                    #it is reference to iterator class (can be useful to extract current depth, or index stack)
85
                    if msg == LCE.CompoundExplorer.MSG_LEAF or msg == LCE.CompoundExplorer.MSG_DIVEDOWN:
86
                        try:
87
                            strMsg =  '    ' * it.curDepth() + shapeInfoString(child)
88
                            if msg == LCE.CompoundExplorer.MSG_DIVEDOWN:
89
                                strMsg += ":"
90
                        except Exception as err:
248 by DeepSOIC
Py3: fix syntax errors
91
                            strMsg = "ERROR: " + str(err)
92
                        strStructure.append(strMsg)
110 by DeepSOIC
V2: renaming .py files
93
            
94
        strSubInfo = []
95
        if sel.HasSubObjects:
96
            subNames = sel.SubElementNames
97
            subObjects = sel.SubObjects
98
            for i in range(0,len(subNames)):
99
                strMsg = subNames[i] + ": "
100
                child = subObjects[i]
101
                
102
                try:
103
                    strMsg += shapeInfoString(child)
104
                except Exception as err:
248 by DeepSOIC
Py3: fix syntax errors
105
                    strMsg += "ERROR: " + str(err)
106
                strSubInfo.append(strMsg)
110 by DeepSOIC
V2: renaming .py files
107
        
108
        allText = u''
109
        if sel.HasSubObjects:
110
            allText += u"Selected " + str(len(sel.SubElementNames)) + u" subelements:\n"
111
            allText += u'\n'.join(strSubInfo) + u'\n\n'
112
        
113
        allText += u'Selected document object:\n'
248 by DeepSOIC
Py3: fix syntax errors
114
        allText += u'  Name = ' + sel.Object.Name + u'\n'
110 by DeepSOIC
V2: renaming .py files
115
        allText += u'  Label = ' + sel.Object.Label + u'\n'
248 by DeepSOIC
Py3: fix syntax errors
116
        allText += u'  Is placement/array = ' + repr(isLattice) + u'\n'
110 by DeepSOIC
V2: renaming .py files
117
        allText += u'Structure: \n'
118
        allText += u'\n'.join(strStructure)
119
        mb = QtGui.QMessageBox()
120
        mb.setIcon(mb.Icon.Information)
231 by DeepSOIC
Inspect: fix null shapes; limit number of lines displayed
121
        lines = allText.split(u"\n") 
122
        if len(lines)>30:
123
            lines = lines[0:30]
124
            lines.append(u"...")
125
        mb.setText(u"\n".join(lines))
114 by DeepSOIC
V2: renames inside files
126
        mb.setWindowTitle(translate("Lattice2_Inspect","Selection info", None))
110 by DeepSOIC
V2: renaming .py files
127
        
128
        btnClose = mb.addButton(QtGui.QMessageBox.StandardButton.Close)
129
        btnCopy = mb.addButton("Copy to clipboard",QtGui.QMessageBox.ButtonRole.ActionRole)
130
        mb.setDefaultButton(btnClose)
131
        mb.exec_()
132
        
133
        if mb.clickedButton() is btnCopy:
134
            cb = QtGui.QClipboard()
135
            cb.setText(allText)
136
137
    def IsActive(self):
138
        if len(FreeCADGui.Selection.getSelectionEx()) == 1:
139
            return True
140
        else:
141
            return False
142
273 by DeepSOIC
FreeCADCmd: fix imports
143
if FreeCAD.GuiUp:
144
    FreeCADGui.addCommand('Lattice2_Inspect',_CommandInspect())
110 by DeepSOIC
V2: renaming .py files
145
192 by DeepSOIC
Group Inspect and ShapeInfo into a dropdown button
146
import lattice2ShapeInfoFeature
147
148
class GroupCommandInspect:
149
    def GetCommands(self):
150
        return ('Lattice2_Inspect', lattice2ShapeInfoFeature.exportedCommands[0]) # a tuple of command names that you want to group
151
152
    def GetDefaultCommand(self): # return the index of the tuple of the default command. This method is optional and when not implemented '0' is used  
153
        return 0
154
155
    def GetResources(self):
156
        return { 'MenuText': 'Inspect:', 'ToolTip': 'Inspect: tools to analyze shape structure.'}
157
        
158
    def IsActive(self): # optional
159
        return True
160
273 by DeepSOIC
FreeCADCmd: fix imports
161
if FreeCAD.GuiUp:
162
    FreeCADGui.addCommand('Lattice2_Inspect_GroupCommand',GroupCommandInspect())
192 by DeepSOIC
Group Inspect and ShapeInfo into a dropdown button
163
164
exportedCommands = ['Lattice2_Inspect_GroupCommand']
110 by DeepSOIC
V2: renaming .py files
165