FreeCAD

Форк
0
/
FeaturePython.py 
723 строки · 21.2 Кб
1
"""
2
Examples for a feature class and its view provider.
3
(c) 2009 Werner Mayer LGPL
4
"""
5

6
__author__ = "Werner Mayer <wmayer@users.sourceforge.net>"
7

8
import FreeCAD, Part, math
9
from FreeCAD import Base
10
from pivy import coin
11

12
class PartFeature:
13
	def __init__(self, obj):
14
		obj.Proxy = self
15

16
class Box(PartFeature):
17
	def __init__(self, obj):
18
		PartFeature.__init__(self, obj)
19
		''' Add some custom properties to our box feature '''
20
		obj.addProperty("App::PropertyLength","Length","Box","Length of the box").Length=1.0
21
		obj.addProperty("App::PropertyLength","Width","Box","Width of the box").Width=1.0
22
		obj.addProperty("App::PropertyLength","Height","Box", "Height of the box").Height=1.0
23

24
	def onChanged(self, fp, prop):
25
		''' Print the name of the property that has changed '''
26
		FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
27

28
	def execute(self, fp):
29
		''' Print a short message when doing a recomputation, this method is mandatory '''
30
		FreeCAD.Console.PrintMessage("Recompute Python Box feature\n")
31
		fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
32

33
class ViewProviderBox:
34
	def __init__(self, obj):
35
		''' Set this object to the proxy object of the actual view provider '''
36
		obj.Proxy = self
37

38
	def attach(self, obj):
39
		''' Setup the scene sub-graph of the view provider, this method is mandatory '''
40
		return
41

42
	def updateData(self, fp, prop):
43
		''' If a property of the handled feature has changed we have the chance to handle this here '''
44
		return
45

46
	def getDisplayModes(self,obj):
47
		''' Return a list of display modes. '''
48
		modes=[]
49
		return modes
50

51
	def getDefaultDisplayMode(self):
52
		''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
53
		return "Shaded"
54

55
	def setDisplayMode(self,mode):
56
		''' Map the display mode defined in attach with those defined in getDisplayModes.
57
		Since they have the same names nothing needs to be done. This method is optional.
58
		'''
59
		return mode
60

61
	def onChanged(self, vp, prop):
62
		''' Print the name of the property that has changed '''
63
		FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
64

65
	def getIcon(self):
66
		''' Return the icon in XMP format which will appear in the tree view. This method is optional
67
		and if not defined a default icon is shown.
68
		'''
69
		return """
70
			/* XPM */
71
			static const char * ViewProviderBox_xpm[] = {
72
			"16 16 6 1",
73
			" 	c None",
74
			".	c #141010",
75
			"+	c #615BD2",
76
			"@	c #C39D55",
77
			"#	c #000000",
78
			"$	c #57C355",
79
			"        ........",
80
			"   ......++..+..",
81
			"   .@@@@.++..++.",
82
			"   .@@@@.++..++.",
83
			"   .@@  .++++++.",
84
			"  ..@@  .++..++.",
85
			"###@@@@ .++..++.",
86
			"##$.@@$#.++++++.",
87
			"#$#$.$$$........",
88
			"#$$#######      ",
89
			"#$$#$$$$$#      ",
90
			"#$$#$$$$$#      ",
91
			"#$$#$$$$$#      ",
92
			" #$#$$$$$#      ",
93
			"  ##$$$$$#      ",
94
			"   #######      "};
95
			"""
96

97
	def __getstate__(self):
98
		''' When saving the document this object gets stored using Python's cPickle module.
99
		Since we have some un-pickable here -- the Coin stuff -- we must define this method
100
		to return a tuple of all pickable objects or None.
101
		'''
102
		return None
103

104
	def __setstate__(self,state):
105
		''' When restoring the pickled object from document we have the chance to set some
106
		internals here. Since no data were pickled nothing needs to be done here.
107
		'''
108
		return None
109

110

111
def makeBox():
112
	doc=FreeCAD.newDocument()
113
	a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Box")
114
	Box(a)
115
	ViewProviderBox(a.ViewObject)
116
	doc.recompute()
117

118
# -----------------------------------------------------------------------------
119

120
class Line:
121
	def __init__(self, obj):
122
		''' Add two point properties '''
123
		obj.addProperty("App::PropertyVector","p1","Line","Start point")
124
		obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(1,0,0)
125
		obj.Proxy = self
126

127
	def execute(self, fp):
128
		''' Print a short message when doing a recomputation, this method is mandatory '''
129
		fp.Shape = Part.makeLine(fp.p1,fp.p2)
130

131
class ViewProviderLine:
132
	def __init__(self, obj):
133
		''' Set this object to the proxy object of the actual view provider '''
134
		obj.Proxy = self
135

136
	def getDefaultDisplayMode(self):
137
		''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
138
		return "Flat Lines"
139

140
def makeLine():
141
	doc=FreeCAD.newDocument()
142
	a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Line")
143
	Line(a)
144
	#ViewProviderLine(a.ViewObject)
145
	a.ViewObject.Proxy=0 # just set it to something different from None
146
	doc.recompute()
147

148
# -----------------------------------------------------------------------------
149

150
class Octahedron:
151
	def __init__(self, obj):
152
		"Add some custom properties to our box feature"
153
		obj.addProperty("App::PropertyLength","Length","Octahedron","Length of the octahedron").Length=1.0
154
		obj.addProperty("App::PropertyLength","Width","Octahedron","Width of the octahedron").Width=1.0
155
		obj.addProperty("App::PropertyLength","Height","Octahedron", "Height of the octahedron").Height=1.0
156
		obj.addProperty("Part::PropertyPartShape","Shape","Octahedron", "Shape of the octahedron")
157
		obj.Proxy = self
158
 
159
	def execute(self, fp):
160
		# Define six vetices for the shape
161
		v1 = FreeCAD.Vector(0,0,0)
162
		v2 = FreeCAD.Vector(fp.Length,0,0)
163
		v3 = FreeCAD.Vector(0,fp.Width,0)
164
		v4 = FreeCAD.Vector(fp.Length,fp.Width,0)
165
		v5 = FreeCAD.Vector(fp.Length/2,fp.Width/2,fp.Height/2)
166
		v6 = FreeCAD.Vector(fp.Length/2,fp.Width/2,-fp.Height/2)
167
		
168
		# Make the wires/faces
169
		f1 = self.make_face(v2,v1,v5)
170
		f2 = self.make_face(v4,v2,v5)
171
		f3 = self.make_face(v3,v4,v5)
172
		f4 = self.make_face(v1,v3,v5)
173
		f5 = self.make_face(v1,v2,v6)
174
		f6 = self.make_face(v2,v4,v6)
175
		f7 = self.make_face(v4,v3,v6)
176
		f8 = self.make_face(v3,v1,v6)
177
		shell=Part.makeShell([f1,f2,f3,f4,f5,f6,f7,f8])
178
		solid=Part.makeSolid(shell)
179
		fp.Shape = solid
180
	# helper method to create the faces
181
	def make_face(self,v1,v2,v3):
182
		wire = Part.makePolygon([v1,v2,v3,v1])
183
		face = Part.Face(wire)
184
		return face
185

186
class ViewProviderOctahedron:
187
	def __init__(self, obj):
188
		"Set this object to the proxy object of the actual view provider"
189
		obj.addProperty("App::PropertyColor","Color","Octahedron","Color of the octahedron").Color=(1.0,0.0,0.0)
190
		obj.Proxy = self
191
 
192
	def attach(self, obj):
193
		"Setup the scene sub-graph of the view provider, this method is mandatory"
194
		self.shaded = coin.SoGroup()
195
		self.wireframe = coin.SoGroup()
196
		self.color = coin.SoBaseColor()
197

198
		self.data=coin.SoCoordinate3()
199
		self.face=coin.SoIndexedFaceSet()
200
 
201
		self.shaded.addChild(self.color)
202
		self.shaded.addChild(self.data)
203
		self.shaded.addChild(self.face)
204
		obj.addDisplayMode(self.shaded,"Shaded");
205
		style=coin.SoDrawStyle()
206
		style.style = coin.SoDrawStyle.LINES
207
		self.wireframe.addChild(style)
208
		self.wireframe.addChild(self.color)
209
		self.wireframe.addChild(self.data)
210
		self.wireframe.addChild(self.face)
211
		obj.addDisplayMode(self.wireframe,"Wireframe");
212
		self.onChanged(obj,"Color")
213
 
214
	def updateData(self, fp, prop):
215
		"If a property of the handled feature has changed we have the chance to handle this here"
216
		# fp is the handled feature, prop is the name of the property that has changed
217
		if prop == "Shape":
218
			s = fp.getPropertyByName("Shape")
219
			self.data.point.setNum(6)
220
			cnt=0
221
			for i in s.Vertexes:
222
				self.data.point.set1Value(cnt,i.X,i.Y,i.Z)
223
				cnt=cnt+1
224
			
225
			self.face.coordIndex.set1Value(0,0)
226
			self.face.coordIndex.set1Value(1,2)
227
			self.face.coordIndex.set1Value(2,1)
228
			self.face.coordIndex.set1Value(3,-1)
229

230
			self.face.coordIndex.set1Value(4,3)
231
			self.face.coordIndex.set1Value(5,2)
232
			self.face.coordIndex.set1Value(6,0)
233
			self.face.coordIndex.set1Value(7,-1)
234
 
235
			self.face.coordIndex.set1Value(8,4)
236
			self.face.coordIndex.set1Value(9,2)
237
			self.face.coordIndex.set1Value(10,3)
238
			self.face.coordIndex.set1Value(11,-1)
239
 
240
			self.face.coordIndex.set1Value(12,1)
241
			self.face.coordIndex.set1Value(13,2)
242
			self.face.coordIndex.set1Value(14,4)
243
			self.face.coordIndex.set1Value(15,-1)
244
 
245
			self.face.coordIndex.set1Value(16,1)
246
			self.face.coordIndex.set1Value(17,5)
247
			self.face.coordIndex.set1Value(18,0)
248
			self.face.coordIndex.set1Value(19,-1)
249
 
250
			self.face.coordIndex.set1Value(20,0)
251
			self.face.coordIndex.set1Value(21,5)
252
			self.face.coordIndex.set1Value(22,3)
253
			self.face.coordIndex.set1Value(23,-1)
254
 
255
			self.face.coordIndex.set1Value(24,3)
256
			self.face.coordIndex.set1Value(25,5)
257
			self.face.coordIndex.set1Value(26,4)
258
			self.face.coordIndex.set1Value(27,-1)
259
 
260
			self.face.coordIndex.set1Value(28,4)
261
			self.face.coordIndex.set1Value(29,5)
262
			self.face.coordIndex.set1Value(30,1)
263
			self.face.coordIndex.set1Value(31,-1)
264

265
	def getDisplayModes(self,obj):
266
		"Return a list of display modes."
267
		modes=[]
268
		modes.append("Shaded")
269
		modes.append("Wireframe")
270
		return modes
271
 
272
	def getDefaultDisplayMode(self):
273
		"Return the name of the default display mode. It must be defined in getDisplayModes."
274
		return "Shaded"
275
 
276
	def setDisplayMode(self,mode):
277
		return mode
278

279
	def onChanged(self, vp, prop):
280
		"Here we can do something when a single property got changed"
281
		FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
282
		if prop == "Color":
283
			c = vp.getPropertyByName("Color")
284
			self.color.rgb.setValue(c[0],c[1],c[2])
285

286
	def getIcon(self):
287
		return """
288
			/* XPM */
289
			static const char * ViewProviderBox_xpm[] = {
290
			"16 16 6 1",
291
			" 	c None",
292
			".	c #141010",
293
			"+	c #615BD2",
294
			"@	c #C39D55",
295
			"#	c #000000",
296
			"$	c #57C355",
297
			"        ........",
298
			"   ......++..+..",
299
			"   .@@@@.++..++.",
300
			"   .@@@@.++..++.",
301
			"   .@@  .++++++.",
302
			"  ..@@  .++..++.",
303
			"###@@@@ .++..++.",
304
			"##$.@@$#.++++++.",
305
			"#$#$.$$$........",
306
			"#$$#######      ",
307
			"#$$#$$$$$#      ",
308
			"#$$#$$$$$#      ",
309
			"#$$#$$$$$#      ",
310
			" #$#$$$$$#      ",
311
			"  ##$$$$$#      ",
312
			"   #######      "};
313
			"""
314
 
315
	def __getstate__(self):
316
		return None
317
 
318
	def __setstate__(self,state):
319
		return None
320

321
def makeOctahedron():
322
	doc=FreeCAD.newDocument()
323
	a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Octahedron")
324
	Octahedron(a)
325
	ViewProviderOctahedron(a.ViewObject)
326
	doc.recompute()
327

328
# -----------------------------------------------------------------------------
329

330
class PointFeature:
331
	def __init__(self, obj):
332
		obj.Proxy = self
333

334
	def onChanged(self, fp, prop):
335
		''' Print the name of the property that has changed '''
336
		return
337

338
	def execute(self, fp):
339
		''' Print a short message when doing a recomputation, this method is mandatory '''
340
		return
341

342
class ViewProviderPoints:
343
	def __init__(self, obj):
344
		''' Set this object to the proxy object of the actual view provider '''
345
		obj.Proxy = self
346

347
	def attach(self, obj):
348
		''' Setup the scene sub-graph of the view provider, this method is mandatory '''
349
		return
350

351
	def updateData(self, fp, prop):
352
		''' If a property of the handled feature has changed we have the chance to handle this here '''
353
		return
354

355
	def getDisplayModes(self,obj):
356
		''' Return a list of display modes. '''
357
		modes=[]
358
		return modes
359

360
	def getDefaultDisplayMode(self):
361
		''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
362
		return "Points"
363

364
	def setDisplayMode(self,mode):
365
		''' Map the display mode defined in attach with those defined in getDisplayModes.
366
		Since they have the same names nothing needs to be done. This method is optional.
367
		'''
368
		return mode
369

370
	def onChanged(self, vp, prop):
371
		''' Print the name of the property that has changed '''
372
		return
373

374
	def getIcon(self):
375
		''' Return the icon in XMP format which will appear in the tree view. This method is optional
376
		and if not defined a default icon is shown.
377
		'''
378
		return """
379
			/* XPM */
380
			static const char * ViewProviderBox_xpm[] = {
381
			"16 16 6 1",
382
			" 	c None",
383
			".	c #141010",
384
			"+	c #615BD2",
385
			"@	c #C39D55",
386
			"#	c #000000",
387
			"$	c #57C355",
388
			"        ........",
389
			"   ......++..+..",
390
			"   .@@@@.++..++.",
391
			"   .@@@@.++..++.",
392
			"   .@@  .++++++.",
393
			"  ..@@  .++..++.",
394
			"###@@@@ .++..++.",
395
			"##$.@@$#.++++++.",
396
			"#$#$.$$$........",
397
			"#$$#######      ",
398
			"#$$#$$$$$#      ",
399
			"#$$#$$$$$#      ",
400
			"#$$#$$$$$#      ",
401
			" #$#$$$$$#      ",
402
			"  ##$$$$$#      ",
403
			"   #######      "};
404
			"""
405

406
	def __getstate__(self):
407
		''' When saving the document this object gets stored using Python's cPickle module.
408
		Since we have some un-pickable here -- the Coin stuff -- we must define this method
409
		to return a tuple of all pickable objects or None.
410
		'''
411
		return None
412

413
	def __setstate__(self,state):
414
		''' When restoring the pickled object from document we have the chance to set some
415
		internals here. Since no data were pickled nothing needs to be done here.
416
		'''
417
		return None
418

419

420
def makePoints():
421
	doc=FreeCAD.newDocument()
422
	import Mesh
423
	m=Mesh.createSphere(5.0).Points
424
	import Points
425
	p=Points.Points()
426

427
	l=[]
428
	for s in m:
429
		l.append(s.Vector)
430

431
	p.addPoints(l)
432

433

434
	a=FreeCAD.ActiveDocument.addObject("Points::FeaturePython","Points")
435
	a.Points=p
436
	PointFeature(a)
437
	ViewProviderPoints(a.ViewObject)
438
	doc.recompute()
439

440
# -----------------------------------------------------------------------------
441

442
class MeshFeature:
443
	def __init__(self, obj):
444
		obj.Proxy = self
445

446
	def onChanged(self, fp, prop):
447
		''' Print the name of the property that has changed '''
448
		return
449

450
	def execute(self, fp):
451
		''' Print a short message when doing a recomputation, this method is mandatory '''
452
		return
453

454
class ViewProviderMesh:
455
	def __init__(self, obj):
456
		''' Set this object to the proxy object of the actual view provider '''
457
		obj.Proxy = self
458

459
	def attach(self, obj):
460
		''' Setup the scene sub-graph of the view provider, this method is mandatory '''
461
		return
462

463
	def getDefaultDisplayMode(self):
464
		''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
465
		return "Shaded"
466

467
	def getIcon(self):
468
		''' Return the icon in XMP format which will appear in the tree view. This method is optional
469
		and if not defined a default icon is shown.
470
		'''
471
		return """
472
			/* XPM */
473
			static const char * ViewProviderBox_xpm[] = {
474
			"16 16 6 1",
475
			" 	c None",
476
			".	c #141010",
477
			"+	c #615BD2",
478
			"@	c #C39D55",
479
			"#	c #000000",
480
			"$	c #57C355",
481
			"        ........",
482
			"   ......++..+..",
483
			"   .@@@@.++..++.",
484
			"   .@@@@.++..++.",
485
			"   .@@  .++++++.",
486
			"  ..@@  .++..++.",
487
			"###@@@@ .++..++.",
488
			"##$.@@$#.++++++.",
489
			"#$#$.$$$........",
490
			"#$$#######      ",
491
			"#$$#$$$$$#      ",
492
			"#$$#$$$$$#      ",
493
			"#$$#$$$$$#      ",
494
			" #$#$$$$$#      ",
495
			"  ##$$$$$#      ",
496
			"   #######      "};
497
			"""
498

499
	def __getstate__(self):
500
		''' When saving the document this object gets stored using Python's cPickle module.
501
		Since we have some un-pickable here -- the Coin stuff -- we must define this method
502
		to return a tuple of all pickable objects or None.
503
		'''
504
		return None
505

506
	def __setstate__(self,state):
507
		''' When restoring the pickled object from document we have the chance to set some
508
		internals here. Since no data were pickled nothing needs to be done here.
509
		'''
510
		return None
511

512

513
def makeMesh():
514
	doc=FreeCAD.newDocument()
515
	import Mesh
516

517
	a=FreeCAD.ActiveDocument.addObject("Mesh::FeaturePython","Mesh")
518
	a.Mesh=Mesh.createSphere(5.0)
519
	MeshFeature(a)
520
	ViewProviderMesh(a.ViewObject)
521
	doc.recompute()
522

523
# -----------------------------------------------------------------------------
524

525
class Molecule:
526
	def __init__(self, obj):
527
		''' Add two point properties '''
528
		obj.addProperty("App::PropertyVector","p1","Line","Start point")
529
		obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(5,0,0)
530

531
		obj.Proxy = self
532

533
	def execute(self, fp):
534
		''' Print a short message when doing a recomputation, this method is mandatory '''
535
		fp.Shape = Part.makeLine(fp.p1,fp.p2)
536

537
class ViewProviderMolecule:
538
	def __init__(self, obj):
539
		''' Set this object to the proxy object of the actual view provider '''
540
		sep1=coin.SoSeparator()
541
		self.trl1=coin.SoTranslation()
542
		sep1.addChild(self.trl1)
543
		sep1.addChild(coin.SoSphere())
544
		sep2=coin.SoSeparator()
545
		self.trl2=coin.SoTranslation()
546
		sep2.addChild(self.trl2)
547
		sep2.addChild(coin.SoSphere())
548
		obj.RootNode.addChild(sep1)
549
		obj.RootNode.addChild(sep2)
550
		# triggers an updateData call so the assignment at the end
551
		obj.Proxy = self
552

553
	def updateData(self, fp, prop):
554
		"If a property of the handled feature has changed we have the chance to handle this here"
555
		# fp is the handled feature, prop is the name of the property that has changed
556
		if prop == "p1":
557
			p = fp.getPropertyByName("p1")
558
			self.trl1.translation=(p.x,p.y,p.z)
559
		elif prop == "p2":
560
			p = fp.getPropertyByName("p2")
561
			self.trl2.translation=(p.x,p.y,p.z)
562

563
	def __getstate__(self):
564
		return None
565
 
566
	def __setstate__(self,state):
567
		return None
568

569
def makeMolecule():
570
	doc=FreeCAD.newDocument()
571
	a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Molecule")
572
	Molecule(a)
573
	ViewProviderMolecule(a.ViewObject)
574
	doc.recompute()
575

576
# -----------------------------------------------------------------------------
577

578
class CircleSet:
579
	def __init__(self, obj):
580
		obj.addProperty("Part::PropertyPartShape","Shape","Circle","Shape")
581
		obj.Proxy = self
582

583
	def execute(self, fp):
584
		pass
585

586

587
class ViewProviderCircleSet:
588
	def __init__(self, obj):
589
		''' Set this object to the proxy object of the actual view provider '''
590
		obj.Proxy = self
591

592
	def attach(self, obj):
593
		self.coords=coin.SoCoordinate3()
594
		self.lines=coin.SoLineSet()
595
		obj.RootNode.addChild(self.coords)
596
		obj.RootNode.addChild(self.lines)
597

598
	def updateData(self, fp, prop):
599
			if prop == "Shape":
600
				edges = fp.getPropertyByName("Shape").Edges
601
				pts=[]
602
				ver=[]
603
				for i in edges:
604
					length=i.Length
605
					ver.append(10)
606
					for j in range(10):
607
						v=i.valueAt(j/9.0*length)
608
						pts.append((v.x,v.y,v.z))
609
				
610
				self.coords.point.setValues(pts)
611
				self.lines.numVertices.setValues(ver)
612

613
	def __getstate__(self):
614
		return None
615
 
616
	def __setstate__(self,state):
617
		return None
618

619
def makeCircleSet():
620
	x=0.5
621
	comp=Part.Compound([])
622
	for j in range (630):
623
		y=0.5
624
		for i in range (630):
625
			c = Part.makeCircle(0.1, Base.Vector(x,y,0), Base.Vector(0,0,1))
626
			#Part.show(c)
627
			comp.add(c)
628
			y=y+0.5
629
		x=x+0.5
630

631
	doc=FreeCAD.newDocument()
632
	a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Circles")
633
	CircleSet(a)
634
	ViewProviderCircleSet(a.ViewObject)
635
	a.Shape=comp
636
	doc.recompute()
637

638
# -----------------------------------------------------------------------------
639

640
class EnumTest:
641
	def __init__(self, obj):
642
		''' Add enum properties '''
643
		obj.addProperty("App::PropertyEnumeration","Enum","","Enumeration").Enum=["One","Two","Three"]
644
		obj.addProperty("App::PropertyEnumeration","Enum2","","Enumeration2").Enum2=["One","Two","Three"]
645
		obj.Proxy = self
646

647
	def execute(self, fp):
648
		return
649

650
class ViewProviderEnumTest:
651
	def __init__(self, obj):
652
		''' Set this object to the proxy object of the actual view provider '''
653
		obj.addProperty("App::PropertyEnumeration","Enum3","","Enumeration3").Enum3=["One","Two","Three"]
654
		obj.addProperty("App::PropertyEnumeration","Enum4","","Enumeration4").Enum4=["One","Two","Three"]
655
		obj.Proxy = self
656

657
	def updateData(self, fp, prop):
658
		print("prop updated:",prop)
659

660
	def __getstate__(self):
661
		return None
662

663
	def __setstate__(self,state):
664
		return None
665

666
def makeEnumTest():
667
	FreeCAD.newDocument()
668
	a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Enum")
669
	EnumTest(a)
670
	ViewProviderEnumTest(a.ViewObject)
671

672
# -----------------------------------------------------------------------------
673

674
class DistanceBolt:
675
	def __init__(self, obj):
676
		''' Add the properties: Length, Edges, Radius, Height '''
677
		obj.addProperty("App::PropertyInteger","Edges","Bolt","Number of edges of the outline").Edges=6
678
		obj.addProperty("App::PropertyLength","Length","Bolt","Length of the edges of the outline").Length=10.0
679
		obj.addProperty("App::PropertyLength","Radius","Bolt","Radius of the inner circle").Radius=4.0
680
		obj.addProperty("App::PropertyLength","Height","Bolt","Height of the extrusion").Height=20.0
681
		obj.Proxy = self
682

683
	def onChanged(self, fp, prop):
684
		if prop == "Edges" or prop == "Length" or prop == "Radius" or prop == "Height":
685
			self.execute(fp)
686

687
	def execute(self, fp):
688
		edges = fp.Edges
689
		if edges < 3:
690
			edges = 3
691
		length = fp.Length
692
		radius = fp.Radius
693
		height = fp.Height
694

695
		m=Base.Matrix()
696
		m.rotateZ(math.radians(360.0/edges))
697

698
		# create polygon
699
		polygon = []
700
		v=Base.Vector(length,0,0)
701
		for i in range(edges):
702
			polygon.append(v)
703
			v = m.multiply(v)
704
		polygon.append(v)
705
		wire = Part.makePolygon(polygon)
706

707
		# create circle
708
		circ=Part.makeCircle(radius)
709

710
		# Create the face with the polygon as outline and the circle as hole
711
		face=Part.Face([wire,Part.Wire(circ)])
712

713
		# Extrude in z to create the final solid
714
		extrude=face.extrude(Base.Vector(0,0,height))
715
		fp.Shape = extrude
716

717
def makeDistanceBolt():
718
	doc=FreeCAD.newDocument()
719
	bolt=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Distance_Bolt")
720
	bolt.Label = "Distance bolt"
721
	DistanceBolt(bolt)
722
	bolt.ViewObject.Proxy=0
723
	doc.recompute()
724

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

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

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

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