FreeCAD

Форк
0
/
CommandCreateJoint.py 
322 строки · 10.8 Кб
1
# SPDX-License-Identifier: LGPL-2.1-or-later
2
# /**************************************************************************
3
#                                                                           *
4
#    Copyright (c) 2023 Ondsel <development@ondsel.com>                     *
5
#                                                                           *
6
#    This file is part of FreeCAD.                                          *
7
#                                                                           *
8
#    FreeCAD is free software: you can redistribute it and/or modify it     *
9
#    under the terms of the GNU Lesser General Public License as            *
10
#    published by the Free Software Foundation, either version 2.1 of the   *
11
#    License, or (at your option) any later version.                        *
12
#                                                                           *
13
#    FreeCAD is distributed in the hope that it will be useful, but         *
14
#    WITHOUT ANY WARRANTY; without even the implied warranty of             *
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU       *
16
#    Lesser General Public License for more details.                        *
17
#                                                                           *
18
#    You should have received a copy of the GNU Lesser General Public       *
19
#    License along with FreeCAD. If not, see                                *
20
#    <https://www.gnu.org/licenses/>.                                       *
21
#                                                                           *
22
# **************************************************************************/
23

24
import os
25
import FreeCAD as App
26

27
from PySide.QtCore import QT_TRANSLATE_NOOP
28

29
if App.GuiUp:
30
    import FreeCADGui as Gui
31
    from PySide import QtCore, QtGui, QtWidgets
32

33
import JointObject
34
from JointObject import TaskAssemblyCreateJoint
35
import UtilsAssembly
36
import Assembly_rc
37

38
# translate = App.Qt.translate
39

40
__title__ = "Assembly Commands to Create Joints"
41
__author__ = "Ondsel"
42
__url__ = "https://www.freecad.org"
43

44

45
def isCreateJointActive():
46
    return UtilsAssembly.isAssemblyGrounded() and UtilsAssembly.assembly_has_at_least_n_parts(2)
47

48

49
def activateJoint(index):
50
    if JointObject.activeTask:
51
        JointObject.activeTask.reject()
52

53
    panel = TaskAssemblyCreateJoint(index)
54
    Gui.Control.showDialog(panel)
55

56

57
class CommandCreateJointFixed:
58
    def __init__(self):
59
        pass
60

61
    def GetResources(self):
62

63
        return {
64
            "Pixmap": "Assembly_CreateJointFixed",
65
            "MenuText": QT_TRANSLATE_NOOP(
66
                "Assembly_CreateJointFixed",
67
                "Create a Fixed Joint",
68
            ),
69
            "Accel": "J",
70
            "ToolTip": "<p>"
71
            + QT_TRANSLATE_NOOP(
72
                "Assembly_CreateJointFixed",
73
                "1 - If an assembly is active : Create a joint permanently locking two parts together, preventing any movement or rotation.",
74
            )
75
            + "</p>"
76
            + "<p>"
77
            + QT_TRANSLATE_NOOP(
78
                "Assembly_CreateJointFixed",
79
                "2 - If a part is active : Position sub parts by matching selected coordinate systems. The second part selected will move.",
80
            )
81
            + "</p>",
82
            "CmdType": "ForEdit",
83
        }
84

85
    def IsActive(self):
86
        if UtilsAssembly.activePart:
87
            return UtilsAssembly.assembly_has_at_least_n_parts(2)
88

89
        return UtilsAssembly.isAssemblyGrounded() and UtilsAssembly.assembly_has_at_least_n_parts(2)
90

91
    def Activated(self):
92
        activateJoint(0)
93

94

95
class CommandCreateJointRevolute:
96
    def __init__(self):
97
        pass
98

99
    def GetResources(self):
100

101
        return {
102
            "Pixmap": "Assembly_CreateJointRevolute",
103
            "MenuText": QT_TRANSLATE_NOOP("Assembly_CreateJointRevolute", "Create Revolute Joint"),
104
            "Accel": "R",
105
            "ToolTip": "<p>"
106
            + QT_TRANSLATE_NOOP(
107
                "Assembly_CreateJointRevolute",
108
                "Create a Revolute Joint: Allows rotation around a single axis between selected parts.",
109
            )
110
            + "</p>",
111
            "CmdType": "ForEdit",
112
        }
113

114
    def IsActive(self):
115
        return isCreateJointActive()
116

117
    def Activated(self):
118
        activateJoint(1)
119

120

121
class CommandCreateJointCylindrical:
122
    def __init__(self):
123
        pass
124

125
    def GetResources(self):
126

127
        return {
128
            "Pixmap": "Assembly_CreateJointCylindrical",
129
            "MenuText": QT_TRANSLATE_NOOP(
130
                "Assembly_CreateJointCylindrical", "Create Cylindrical Joint"
131
            ),
132
            "Accel": "C",
133
            "ToolTip": "<p>"
134
            + QT_TRANSLATE_NOOP(
135
                "Assembly_CreateJointCylindrical",
136
                "Create a Cylindrical Joint: Enables rotation along one axis while permitting movement along the same axis between assembled parts.",
137
            )
138
            + "</p>",
139
            "CmdType": "ForEdit",
140
        }
141

142
    def IsActive(self):
143
        return isCreateJointActive()
144

145
    def Activated(self):
146
        activateJoint(2)
147

148

149
class CommandCreateJointSlider:
150
    def __init__(self):
151
        pass
152

153
    def GetResources(self):
154

155
        return {
156
            "Pixmap": "Assembly_CreateJointSlider",
157
            "MenuText": QT_TRANSLATE_NOOP("Assembly_CreateJointSlider", "Create Slider Joint"),
158
            "Accel": "S",
159
            "ToolTip": "<p>"
160
            + QT_TRANSLATE_NOOP(
161
                "Assembly_CreateJointSlider",
162
                "Create a Slider Joint: Allows linear movement along a single axis but restricts rotation between selected parts.",
163
            )
164
            + "</p>",
165
            "CmdType": "ForEdit",
166
        }
167

168
    def IsActive(self):
169
        return isCreateJointActive()
170

171
    def Activated(self):
172
        activateJoint(3)
173

174

175
class CommandCreateJointBall:
176
    def __init__(self):
177
        pass
178

179
    def GetResources(self):
180

181
        return {
182
            "Pixmap": "Assembly_CreateJointBall",
183
            "MenuText": QT_TRANSLATE_NOOP("Assembly_CreateJointBall", "Create Ball Joint"),
184
            "Accel": "B",
185
            "ToolTip": "<p>"
186
            + QT_TRANSLATE_NOOP(
187
                "Assembly_CreateJointBall",
188
                "Create a Ball Joint: Connects parts at a point, allowing unrestricted movement as long as the connection points remain in contact.",
189
            )
190
            + "</p>",
191
            "CmdType": "ForEdit",
192
        }
193

194
    def IsActive(self):
195
        return isCreateJointActive()
196

197
    def Activated(self):
198
        activateJoint(4)
199

200

201
class CommandCreateJointDistance:
202
    def __init__(self):
203
        pass
204

205
    def GetResources(self):
206

207
        return {
208
            "Pixmap": "Assembly_CreateJointDistance",
209
            "MenuText": QT_TRANSLATE_NOOP("Assembly_CreateJointDistance", "Create Distance Joint"),
210
            "Accel": "D",
211
            "ToolTip": "<p>"
212
            + QT_TRANSLATE_NOOP(
213
                "Assembly_CreateJointDistance",
214
                "Create a Distance Joint: Fix the distance between the selected objects.",
215
            )
216
            + "</p>",
217
            "CmdType": "ForEdit",
218
        }
219

220
    def IsActive(self):
221
        # return False
222
        return isCreateJointActive()
223

224
    def Activated(self):
225
        activateJoint(5)
226

227

228
def createGroundedJoint(obj):
229
    assembly = UtilsAssembly.activeAssembly()
230
    if not assembly:
231
        return
232

233
    joint_group = UtilsAssembly.getJointGroup(assembly)
234

235
    obj.Label = obj.Label + " 🔒"
236
    ground = joint_group.newObject("App::FeaturePython", "GroundedJoint")
237
    JointObject.GroundedJoint(ground, obj)
238
    JointObject.ViewProviderGroundedJoint(ground.ViewObject)
239
    return ground
240

241

242
class CommandToggleGrounded:
243
    def __init__(self):
244
        pass
245

246
    def GetResources(self):
247

248
        return {
249
            "Pixmap": "Assembly_ToggleGrounded",
250
            "MenuText": QT_TRANSLATE_NOOP("Assembly_ToggleGrounded", "Toggle grounded"),
251
            "Accel": "G",
252
            "ToolTip": "<p>"
253
            + QT_TRANSLATE_NOOP(
254
                "Assembly_ToggleGrounded",
255
                "Grounding a part permanently locks its position in the assembly, preventing any movement or rotation. You need at least one grounded part before starting to assemble.",
256
            )
257
            + "</p>",
258
            "CmdType": "ForEdit",
259
        }
260

261
    def IsActive(self):
262
        return (
263
            UtilsAssembly.isAssemblyCommandActive()
264
            and UtilsAssembly.assembly_has_at_least_n_parts(1)
265
        )
266

267
    def Activated(self):
268
        assembly = UtilsAssembly.activeAssembly()
269
        if not assembly:
270
            return
271

272
        joint_group = UtilsAssembly.getJointGroup(assembly)
273

274
        selection = Gui.Selection.getSelectionEx("*", 0)
275
        if not selection:
276
            return
277

278
        App.setActiveTransaction("Toggle grounded")
279
        for sel in selection:
280
            # If you select 2 solids (bodies for example) within an assembly.
281
            # There'll be a single sel but 2 SubElementNames.
282
            for sub in sel.SubElementNames:
283
                # Only objects within the assembly.
284
                objs_names, element_name = UtilsAssembly.getObjsNamesAndElement(sel.ObjectName, sub)
285
                if assembly.Name not in objs_names:
286
                    continue
287

288
                full_element_name = UtilsAssembly.getFullElementName(sel.ObjectName, sub)
289
                obj = UtilsAssembly.getObject(full_element_name)
290
                part_containing_obj = UtilsAssembly.getContainingPart(full_element_name, obj)
291

292
                # Check if part is grounded and if so delete the joint.
293
                ungrounded = False
294
                for joint in joint_group.Group:
295
                    if (
296
                        hasattr(joint, "ObjectToGround")
297
                        and joint.ObjectToGround == part_containing_obj
298
                    ):
299
                        # Remove grounded tag.
300
                        if part_containing_obj.Label.endswith(" 🔒"):
301
                            part_containing_obj.Label = part_containing_obj.Label[:-2]
302
                        doc = App.ActiveDocument
303
                        doc.removeObject(joint.Name)
304
                        doc.recompute()
305
                        ungrounded = True
306
                        break
307
                if ungrounded:
308
                    continue
309

310
                # Create groundedJoint.
311
                createGroundedJoint(part_containing_obj)
312
        App.closeActiveTransaction()
313

314

315
if App.GuiUp:
316
    Gui.addCommand("Assembly_ToggleGrounded", CommandToggleGrounded())
317
    Gui.addCommand("Assembly_CreateJointFixed", CommandCreateJointFixed())
318
    Gui.addCommand("Assembly_CreateJointRevolute", CommandCreateJointRevolute())
319
    Gui.addCommand("Assembly_CreateJointCylindrical", CommandCreateJointCylindrical())
320
    Gui.addCommand("Assembly_CreateJointSlider", CommandCreateJointSlider())
321
    Gui.addCommand("Assembly_CreateJointBall", CommandCreateJointBall())
322
    Gui.addCommand("Assembly_CreateJointDistance", CommandCreateJointDistance())
323

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.