-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathDesign456_Extrude.py
219 lines (207 loc) · 10 KB
/
Design456_Extrude.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
#
# ***************************************************************************
# * *
# * This file is a part of the Open Source Design456 Workbench - FreeCAD. *
# * *
# * Copyright (C) 2022 *
# * *
# * *
# * This library is free software; you can redistribute it and/or *
# * modify it under the terms of the GNU Lesser General Public *
# * License as published by the Free Software Foundation; either *
# * version 2 of the License, or (at your option) any later version. *
# * *
# * This library 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 *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with this library; if not, If not, see *
# * <http://www.gnu.org/licenses/>. *
# * *
# * Author : Mariwan Jalal mariwan.jalal@gmail.com *
# ***************************************************************************
import os
import sys
import FreeCAD as App
import FreeCADGui as Gui
import Design456Init
from PySide import QtGui, QtCore
import Draft
import Part
import FACE_D as faced
from time import time as _time, sleep as _sleep
from draftutils.translate import translate # for translation
import math
__updated__ = '2022-05-26 22:39:45'
class Design456_Extrude:
def ExtractFace(self, nTObj=None):
try:
newlistObj = []
newObj = None
if nTObj is None:
fullname = "ExtractedFace"
newObj = App.ActiveDocument.addObject(
"Part::Feature", fullname)
if (self.selectedObj[0].HasSubObjects):
newObj.Shape = self.selectedObj[0].SubObjects[0].copy()
App.ActiveDocument.recompute()
return newObj
else:
#We have the whole object selected, take all faces and return a list
xx = 0
for obj in self.selectedObj[0].Object.Shape.Faces:
fullname = "Face"+str(xx)
xx = xx+1
newObj = App.ActiveDocument.addObject(
"Part::Feature", fullname)
newObj.Shape = obj.copy()
App.ActiveDocument.recompute()
newlistObj.append(newObj) # Extracted Face.
return newlistObj
else:
print(type(nTObj))
if type(nTObj) != list and type(nTObj) != tuple:
TObj = [nTObj]
else:
TObj = nTObj
xx = 0
for obj in TObj:
fullname = "Face"+str(xx)
xx = xx+1
newObj = App.ActiveDocument.addObject(
"Part::Feature", fullname)
newObj.Shape = obj.copy()
App.ActiveDocument.recompute()
newlistObj.append(newObj) # Extracted Face.
return newlistObj
except Exception as err:
App.Console.PrintError("'Extract Face' Failed. "
"{err}\n".format(err=str(err)))
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
def Activated(self):
try:
AllObjects = []
self.extrusionLength = -(QtGui.QInputDialog.getDouble(
None, "Extrusion Length", "Length:", 0, -10000.0, 10000.0, 2)[0])
if self.extrusionLength == 0.0:
return
self.selectedObj = Gui.Selection.getSelectionEx()
if (len(self.selectedObj) < 1):
# An object must be selected
errMessage = "Select a face to use Extrude"
faced.errorDialog(errMessage)
return
if len(self.selectedObj) == 1:
# It is only one object. But might have different faces
if (self.selectedObj[0].HasSubObjects):
# Here it can be a face with multiple faces
# Or a 3D object with multiple faces?
result = self.selectedObj[0].SubObjects
AllObjects = self.ExtractFace(result)
else:
# Only One object that doesn't have subobjects
if isinstance(self.selectedObj[0].Object.Shape, Part.Face):
# It is a face. i.e. the object itself is a face only
AllObjects = [self.selectedObj[0].Object]
else:
# It is a face of a 3D object
_nResult= self.ExtractFace()
if type(_nResult)==list:
AllObjects=_nResult
else:
AllObjects = [_nResult]
else:
# We have multiple objects selected. Could be faces, 3D objects
# or mixed
result = []
result.clear()
for i in range(0, len(self.selectedObj)):
_obj = self.selectedObj[i]
if (hasattr(_obj, "HasSubObjects")):
if(_obj.HasSubObjects):
for nobj in _obj.SubObjects:
if type(nobj) == Part.Face:
result.append(nobj)
else:
result.append(_obj)
AllObjects = self.ExtractFace(result)
self.ExtrudeFace(AllObjects)
except Exception as err:
App.Console.PrintError("'Design456_Extrude' Failed. "
"{err}\n".format(err=str(err)))
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
def ExtrudeFace(self, allObjects):
try:
for obj in allObjects:
App.ActiveDocument.openTransaction(
translate("Design456", "Extrude"))
m = obj
f = App.ActiveDocument.addObject(
'Part::Extrusion', 'ExtrudeOriginal')
# section direction
yL = m.Shape.Faces[0].CenterOfMass
uv = m.Shape.Faces[0].Surface.parameter(yL)
nv = m.Shape.Faces[0].normalAt(uv[0], uv[1])
direction = yL.sub(nv + yL)
direction = App.Vector(round(direction.x, 2), round(
direction.y, 2), round(direction.z, 2))
f.Dir = direction
f.Base = m
# F.DirMode causes too many failure. Some faces needs custom, other needs Normal.
# Difficult to know when you use each of them.
if (f.Dir.x != 1 or f.Dir.y != 1 or f.Dir.z != 1):
f.DirMode = "Custom"
else:
f.DirMode = "Normal"
f.DirLink = None # Above statement != always correct. Some faces require 'custom'
f.LengthFwd = self.extrusionLength
f.LengthRev = 0.0
f.Solid = True
f.Reversed = False
f.Symmetric = False
f.TaperAngle = 0.0
f.TaperAngleRev = 0.0
r = App.Rotation(App.Vector(0, 0, 0), direction)
f.Dir = direction
# Make a simple copy of the object
App.ActiveDocument.recompute()
newShape = Part.getShape(
f, '', needSubElement=False, refine=False)
newObj = App.ActiveDocument.addObject(
'Part::Feature', 'Extrude')
newObj.Shape = newShape
App.ActiveDocument.recompute()
# if something went wrong .. delete all new objects.
if newObj.isValid() is False:
App.ActiveDocument.removeObject(newObj.Name)
App.ActiveDocument.removeObject(f.Name)
# Shape != OK
errMessage = "Failed to extrude the shape"
faced.errorDialog(errMessage)
else:
App.ActiveDocument.recompute()
App.ActiveDocument.removeObject(f.Name)
App.ActiveDocument.removeObject(m.Name)
App.ActiveDocument.commitTransaction() # undo reg.
App.ActiveDocument.recompute()
except Exception as err:
App.Console.PrintError("'Design456_Extrude' Failed. "
"{err}\n".format(err=str(err)))
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
def GetResources(self):
return {
'Pixmap': Design456Init.ICON_PATH + 'Extrude.svg',
'MenuText': 'Extrude',
'ToolTip': 'Extrude'
}
Gui.addCommand('Design456_Extrude', Design456_Extrude())