29
62
#* Foundation, Inc., *
30
63
#* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
32
#****************************************************************************#
65
#****************************************************************************
66
##With kicad StepUp you’ll get an exact representation of your physical board in Native 3D PCB
35
# collision and proximity as microelly
37
70
# upgrade kicadstepup version
38
# enable confirm on exit
39
71
# resized font size
40
72
# add bbox and volume images on the starter guide
41
73
# add ksu config more detailed description
42
74
# complete volume_minimum config in doc
46
from __future__ import unicode_literals
75
# improved OSX QtGui File Open
76
# better arc and line import
78
# collision and proximity as microelly
80
# enable confirm on exit
81
# replace FreeCAD.Console.Message -> say
83
# added messages on missing emn files
84
# added messages on missing models
85
# added path to adapt your KISYS3DMOD
86
# added blacklist for unwanted modules
87
# added messages on blacklisted modules
88
# added pcb color attribute
89
# added bounding box option
90
# added bounding box white list to leave real model on connector or peripheral models
91
# added auxorigin, base origin, base point placement option
92
# added vrml models z-rotation angle
93
# added virtual models option
94
# added fusion export option
95
# added saving in native format, export to STEP
96
# added arcs and circles for calculate board position
97
# added idf_to_origin flag for version >6091
98
# added reset properties for FC 016 bug
99
# added ${KIPRJMOD} support
100
# added v3,v4 pcb version support
101
# added multi 3D vrml model support
102
# added compatibility to kicad version >=3
103
# added auto color assigning in bboxes
104
# added minimum volume per model
105
# added minimum height per model
106
# updated findPcbCenter method
107
# added support for .stp extension beside .step
108
# added support for .igs extension beside .step
109
# added support for .iges extension beside .step
110
# because of hole sovrapposition prob...
111
# cutting hole by hole instead of hole compound
112
# added holes_solid var
113
# to have holes as solid to garantee cutting
114
# handled single circle
115
# used OpenSCAD2Dgeom instead of wire + face (best option)
116
# http://www.freecadweb.org/wiki/index.php?title=Macro_Creating_faces_from_a_DXF_file
117
# fixed unicode text parsing
118
# double option .kicad_pcb .emn
119
# in case of non coincidences .emn is more tolerant
120
# try to build wires on closed shaped for make the cutting faster
121
# try to optimize cutting changing creation/type of holes
122
# manage bklist and volume
123
# accept with or without /\ at the end of 3Dpath
124
# search models in KIPRJMOD and in KISYS3DMOD
125
# removed unicode chars in .kicad_pcb
126
# exported wrl, step from python
127
# reload & display ini cfg file
128
# display/edit ini file with syntax highlight
129
# msg first ksu config
130
# added warning for import step multi part
131
# added warning in load footprint and in placing step mod if x,y and scale are different from 0 0 0 and 1 1 1
132
# non stopping warning for footprint
133
# added command line args to load board(/emn)
134
# avoid argv in memory in case of opened from command line
135
# used multi cut also for footprint too
136
# enabled loadB, loadI, loadF with filename=None to align Mod and Macro
137
# enabled Macro & Mod
138
# added ico tools info
139
# added checkbox export_2_step
140
# added export2STEP var in ini file
143
# most clean code and comments done
146
# message error for bad config
147
# enable upper case configparser optionxform
148
# http://stackoverflow.com/questions/19359556/configparser-reads-capital-keys-and-make-them-lower-case
149
# use isInside/common ( TopoShape ) to cut only intersection objs
151
# evaluate python occ for step exporting without triangulation
152
# test option placement
153
# check line 772 abs ZMax = height?
154
# add checkbox virtual
155
# fix fonts for html and new buttons
157
# try to close non closed wire
158
# from Macro_JointWire
163
import FreeCAD, FreeCADGui
48
166
from PySide import QtGui, QtCore
167
#QtGui.QSyntaxHighlighter, QtGui.QTextCharFormat, QtGui.QBrush
168
#https://github.com/JimmXinu/FanFicFare/blob/master/calibre-plugin/basicinihighlighter.py
169
#http://fanficdownloader.googlecode.com/hg/calibre-plugin/basicinihighlighter.py
50
171
from time import sleep
51
from math import sqrt, tan, atan, atan2, degrees, radians, hypot, sin, cos, pi
52
#from math import sqrt, atan2, sin, cos, radians, pi, hypot, atan
172
from math import sqrt, tan, atan, atan2, degrees, radians, hypot, sin, cos, pi, fmod
174
from collections import namedtuple
57
175
from FreeCAD import Base
177
from os.path import expanduser
180
import OpenSCAD2Dgeom
182
from math import sqrt, atan, sin, cos, radians, degrees, pi
187
from PySide import QtCore, QtGui
189
import OpenSCADFeatures
190
#from codecs import open #maui to verify
194
pythonopen = __builtin__.open # to distinguish python built-in open function from the one declared here
196
## Constant definitions
197
___ver___ = "3.0.3.3" #reviewing FPL
198
__title__ = "kicad_StepUp"
199
__author__ = "maurice & mg"
200
__Comment__ = 'Kicad STEPUP(TM) (3D kicad board and models exported to STEP) for FreeCAD'
201
___ver_ksu___ = "1.0.1.9 25/11/2015 COPIA!!!"
202
IDF_ImporterVersion="3.9.2"
203
__Icon__ = "stepup.png"
205
global userCancelled, userOK, show_mouse_pos, min_val, last_file_path, resetP
206
global start_time, show_messages
208
global real_board_pos_x, real_board_pos_y, board_base_point_x, board_base_point_y
209
global ksu_config_fname, ini_content, configFilePath
210
global models3D_prefix, blacklisted_model_elements, col, colr, colg, colb
211
global bbox, volume_minimum, height_minimum, idf_to_origin, aux_orig
212
global base_orig, base_point, bbox_all, bbox_list, whitelisted_model_elements
213
global fusion, addVirtual, blacklisted_models, exportFusing, min_drill_size
214
global last_fp_path, last_pcb_path, plcmnt, xp, yp, exportFusing
218
global rot_wrl, test_flag, test_flag_pads
220
#global module_3D_dir
221
userCancelled = "Cancelled"
223
show_mouse_pos = True
224
#module_3D_dir="C:/Cad/Progetti_K/a_mod"
226
conflict_tolerance=1e-6 #volume tolerance
228
bbox_r_col=(0.411765, 0.411765, 0.411765) #dimgrey
229
bbox_c_col=(0.823529, 0.411765, 0.117647) #chocolate
230
bbox_x_col=(0.862745, 0.862745, 0.862745) #gainsboro
231
bbox_l_col=(0.333333, 0.333333, 0.333333) #sgidarkgrey
232
bbox_IC_col=(0.156863, 0.156863, 0.156863) #sgiverydarkgrey
233
bbox_default_col=(0.439216, 0.501961, 0.564706) #slategrey
243
disable_cutting=False
246
##ignore_utf8=False not used
249
#show_messages=False # mauitest
251
global export_board_2step
252
#export_board_2step=False
255
current_milli_time = lambda: int(round(time.time() * 1000))
258
#clearing previous messages
259
mw=FreeCADGui.getMainWindow()
260
c=mw.findChild(QtGui.QPlainTextEdit, "Python console")
262
r=mw.findChild(QtGui.QTextEdit, "Report view")
268
# points: [Vector, Vector, ...]
269
# faces: [(pi, pi, pi), ], pi: point index
270
# color: (Red, Green, Blue), values range from 0 to 1.0
271
Mesh = namedtuple('Mesh', ['points', 'faces', 'color', 'transp'])
273
from sys import platform as _platform
277
def insert(filename, other):
278
if os.path.exists(filename):
281
FreeCAD.Console.PrintError("File does not exist.\n")
282
reply = QtGui.QMessageBox.information(None,"info", "File does not exist.\n")
285
#reply = QtGui.QMessageBox.information(None,"info", filename)
286
#onLoadBoard_cmd(filename)
287
ext = os.path.splitext(os.path.basename(filename))[1]
288
if ext==".kicad_pcb":
289
onLoadBoard(filename)
291
onLoadBoard_idf(filename)
292
elif ext==".kicad_mod":
293
onLoadFootprint(filename)
296
FreeCAD.Console.PrintMessage(msg)
299
FreeCAD.Console.PrintWarning(msg)
300
FreeCAD.Console.PrintWarning('\n')
303
FreeCAD.Console.PrintError(msg)
304
FreeCAD.Console.PrintWarning('\n')
306
def cfgParsWrite(configFilePath):
308
global models3D_prefix, blacklisted_model_elements, col, colr, colg, colb
309
global bbox, volume_minimum, height_minimum, idf_to_origin, aux_orig
310
global base_orig, base_point, bbox_all, bbox_list, whitelisted_model_elements
311
global fusion, addVirtual, blacklisted_models, exportFusing, min_drill_size
312
global last_fp_path, last_pcb_path, plcmnt, xp, yp, exportFusing, export_board_2step
314
configParser.set('last_footprint_path', 'last_fp_path', last_fp_path)
315
configParser.set('last_pcb_path', 'last_pcb_path', last_pcb_path)
316
if export_board_2step:
317
configParser.set('export', 'export_to_step', "yes")
319
configParser.set('export', 'export_to_step', "no")
320
#configParser.set('last_fp_path', ';; last footprint file path used')
321
configParser.set('info', default_ksu_msg[0])
322
configParser.set('prefix3D', default_ksu_msg[1])
323
configParser.set('PcbColor', default_ksu_msg[2])
324
configParser.set('Blacklist', default_ksu_msg[3])
325
configParser.set('BoundingBox', default_ksu_msg[4])
326
configParser.set('Placement', default_ksu_msg[5])
327
configParser.set('Virtual', default_ksu_msg[6])
328
configParser.set('ExportFuse', default_ksu_msg[7])
329
configParser.set('minimum_drill_size', default_ksu_msg[8])
330
configParser.set('last_pcb_path', default_ksu_msg[9])
331
configParser.set('last_footprint_path', default_ksu_msg[10])
332
configParser.set('export', default_ksu_msg[11])
333
# save to the config file
334
with __builtin__.open(configFilePath, 'wb') as configfile:
335
configParser.write(configfile)
336
#configFilePath.close() already closed
340
def cfgParsRead(configFilePath):
342
global models3D_prefix, blacklisted_model_elements, col, colr, colg, colb
343
global bbox, volume_minimum, height_minimum, idf_to_origin, aux_orig
344
global base_orig, base_point, bbox_all, bbox_list, whitelisted_model_elements
345
global fusion, addVirtual, blacklisted_models, exportFusing, min_drill_size
346
global last_fp_path, last_pcb_path, plcmnt, xp, yp, exportFusing, export_board_2step
349
blacklisted_model_elements=''
350
#col=''; col='0.0,0.5,0.0,green'; # color
351
col=''; col='0.0,0.0,1.0,blue'; # color
354
volume_minimum=0 #0.8 ##1 #mm^3, 0 skipped #global var default
355
height_minimum=0 #0.8 ##1 #mm, 0 skipped #global var default
356
## to debug quickly put show_messages=False
357
### from release 6091 this flag enables the option to place IDF exported to origin
360
aux_orig=0;base_orig=0;base_point=0
361
bbox_all=0; bbox_list=0; whitelisted_model_elements=''
362
fusion=False; addVirtual=0
363
configParser.read(configFilePath)
364
models3D_prefix = configParser.get('prefix3D', 'prefix3D_1')
365
if not models3D_prefix.endswith('/'):
366
if not models3D_prefix.endswith('\\'):
368
#say(models3D_prefix+'\n')
369
pcb_color = configParser.get('PcbColor', 'pcb_color')
370
bklist = configParser.get('Blacklist', 'bklist')
371
bbox_opt = configParser.get('BoundingBox', 'bbox')
372
plcmnt = configParser.get('Placement', 'placement')
373
virtual = configParser.get('Virtual', 'virt')
374
exportFusing = configParser.get('ExportFuse', 'exportFusing')
375
min_drill_size = float(configParser.get('minimum_drill_size', 'min_drill_size'))
376
last_pcb_path = configParser.get('last_pcb_path', 'last_pcb_path')
377
last_fp_path = configParser.get('last_footprint_path', 'last_fp_path')
378
export2S = configParser.get('export', 'export_to_STEP')
379
if "yes" in export2S:
380
export_board_2step=True
382
export_board_2step=False
383
if bklist.find('none') !=-1:
384
blacklisted_model_elements=''
385
elif bklist.find('volume') !=-1:
386
vval=bklist.strip('\r\n')
387
vvalue=vval.split("=")
388
volume_minimum=float(vvalue[1])
389
#reply = QtGui.QMessageBox.information(None,"info ...","volume "+str(volume_minimum))
390
elif bklist.find('height') !=-1:
391
vval=bklist.strip('\r\n')
392
vvalue=vval.split("=")
393
height_minimum=float(vvalue[1])
394
#reply = QtGui.QMessageBox.information(None,"info ...","height "+str(height_minimum))
396
blacklisted_model_elements=bklist.strip('\r\n')
397
blacklisted_models=blacklisted_model_elements.split(",")
398
col=pcb_color.strip('\r\n')
399
if bbox_opt.upper().find('ALL') !=-1:
401
whitelisted_model_elements=''
403
if bbox_opt.upper().find('LIST') !=-1:
405
whitelisted_model_elements=bbox_opt.strip('\r\n')
406
#whitelisted_models=whitelisted_model_elements.split(",")
407
if plcmnt.find('AuxOrigin') !=-1:
409
#whitelisted_model_elements=''
410
if plcmnt.find('BaseOrigin') !=-1:
412
if plcmnt.find('BasePoint') !=-1:
414
basepoint=plcmnt.strip('\r\n')
415
coords_BP=basepoint.split(";")
416
xp=float(coords_BP[1]);yp=float(coords_BP[2])
417
if plcmnt.find('AutoAdjust') !=-1:
419
if virtual.lower().find('addvirtual') !=-1:
421
if exportFusing.lower().find('fuseall') !=-1:
423
say('3D models prefix='+models3D_prefix+'\rpcb color='+col+'\r')
424
#cfg_parameters.append(models3D_prefix)
425
#cfg_parameters.append(col)
426
say('blacklist modules '+blacklisted_model_elements+'\r')
427
#cfg_parameters.append(blacklisted_model_elements)
428
say('volume '+str(volume_minimum)+' heigh '+str(height_minimum)+'\r')
429
#cfg_parameters.append(volume_minimum)
430
say('bounding box option '+str(bbox_all)+' whitelist '+whitelisted_model_elements+'\r')
431
#cfg_parameters.append(bbox_all);cfg_parameters.append(whitelisted_model_elements)
432
say('placement board @ '+plcmnt+'\r')
433
say('last fp path '+last_fp_path+'\r')
434
say('last brd path '+last_pcb_path+'\r')
435
#cfg_parameters.append(plcmnt);cfg_parameters.append(last_fp_path)
436
#cfg_parameters.append(last_pcb_path)
437
say('virtual models '+virtual+'\r')
438
say('export fusing option '+exportFusing+'\r')
439
#cfg_parameters.append(virtual);cfg_parameters.append(exportFusing)
440
say ('minimum drill size '+str(min_drill_size)+'mm\n')
441
say ('export to STEP '+str(export_board_2step)+'\n')
442
#cfg_parameters.append(min_drill_size);
444
#FreeCADGui.ActiveDocument.getObject("Board_outline").ShapeColor = (0.3333,0.3333,0.4980)
446
colr=float(col[0]);colg=float(col[1]);colb=float(col[2])
447
##cfg_parameters = (models3D_prefix,blacklisted_model_elements,col,bbox,volume_minimum,height_minimum
448
#cfg_parameters.append(colr);cfg_parameters.append(colg);cfg_parameters.append(colb)
449
#return cfg_parameters
452
def shapeToMesh(shape, color, transp, mesh_deviation, scale=None):
453
#mesh_deviation=0.1 #the smaller the best quality, 1 coarse
454
#say(mesh_deviation+'\n')
455
mesh_data = shape.tessellate(mesh_deviation)
456
points = mesh_data[0]
458
points = map(lambda p: p*scale, points)
459
newMesh= Mesh(points = points,
460
faces = mesh_data[1],
461
color = color, transp=transp)
464
def exportVRML(objects, filepath):
465
"""Export given list of Mesh objects to a VRML file.
467
`Mesh` structure is defined at root."""
469
with __builtin__.open(filepath, 'w') as f:
470
# write the standard VRML header
471
f.write("#VRML V2.0 utf8\n\n")
473
f.write("Shape { geometry IndexedFaceSet \n{ coordIndex [")
474
# write coordinate indexes for each face
475
f.write(','.join("%d,%d,%d,-1" % f for f in obj.faces))
476
f.write("]\n") # closes coordIndex
477
f.write("coord Coordinate { point [")
478
# write coordinate points for each vertex
479
#f.write(','.join('%.3f %.3f %.3f' % (p.x, p.y, p.z) for p in obj.points))
480
f.write(','.join('%.3f %.3f %.3f' % (p.x, p.y, p.z) for p in obj.points))
481
f.write("]\n}") # closes Coordinate
482
#shape_col=(1.0, 0.0, 0.0)#, 0.0)
483
f.write("}\n") # closes points
485
shape_col=obj.color[:-1] #remove last item
487
shape_transparency=obj.transp
488
f.write("appearance Appearance{material Material{diffuseColor %f %f %f\n" % shape_col)
489
f.write("transparency %f}}" % shape_transparency)
490
f.write("}\n") # closes Shape
491
say(filepath+' written\n')
494
def export(componentObjs, fullfilePathName, scale=None):
495
""" Exports given ComponentModel object using FreeCAD.
497
`componentObjs` : a ComponentObjs list
498
`fullfilePathName` : name of the FC file, extension is important
503
exp_name=componentObjs[0].Label
504
path, fname = os.path.split(fullfilePathName)
505
fname=os.path.splitext(fname)[0]
507
filename=path+os.sep+exp_name+'.wrl'
509
filename=path+os.sep+exp_name+'_1_1.wrl'
512
mesh_deviation_default=0.03 # 0.03 or 0.1
513
mesh_dev=mesh_deviation_default #the smaller the best quality, 1 coarse
514
if os.path.exists(filename):
516
QtGui.qApp.restoreOverrideCursor()
517
reply = QtGui.QMessageBox.question(None, "Info", filename+"\nwrl file exists, overwrite?",
518
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No)
519
if reply == QtGui.QMessageBox.Yes:
520
# this is where the code relevant to a 'Yes' answer goes
523
if reply == QtGui.QMessageBox.No:
524
# this is where the code relevant to a 'No' answer goes
528
reply = QtGui.QInputDialog.getText(None, "Mesh Deviation","Mesh Deviation (the smaller the better quality)",QtGui.QLineEdit.Normal,str(mesh_deviation_default))
532
mesh_dev = float (replyText)
534
# user clicked Cancel
535
replyText = reply[0] # which will be "" if they clicked Cancel
536
mesh_dev=mesh_deviation_default #the smaller the best quality, 1 coarse
542
for obj in componentObjs:
544
color.append(FreeCADGui.ActiveDocument.getObject(obj.Name).ShapeColor)
545
transparency.append(FreeCADGui.ActiveDocument.getObject(obj.Name).Transparency/100.0)
547
#say(FreeCADGui.ActiveDocument.getObject(obj.Name).DiffuseColor)
548
Diffuse_color.append(FreeCADGui.ActiveDocument.getObject(obj.Name).DiffuseColor)
551
#say("diffuse color")
556
for obj in componentObjs:
558
single_color=Diffuse_color[i];
561
#say(len(single_color))
562
#colors less then faces
563
if(len(single_color)!=len(shape1.Faces)):
565
#copy color to all faces
566
#else copy singolar colors for faces
569
for color in single_color:
570
color_vector.append(color)
573
for index in range(len(shape1.Faces)):
575
#say(color_vector[indexColor])
576
singleFace=shape1.Faces[index]
578
#say(color_vector[indexColor])
579
meshes.append(shapeToMesh(singleFace, color_vector[indexColor], transparency[i], mesh_dev, scale))
581
#say(single_color[0])
582
meshes.append(shapeToMesh(singleFace, single_color[0], transparency[i], mesh_dev, scale))
583
indexColor=indexColor+1
584
#meshes.append(shapeToMesh(face, Diffuse_color[i], transparency[i], scale))
588
exportVRML(meshes, filename)
592
def go_export(fPathName):
593
sel = FreeCADGui.Selection.getSelection()
595
FreeCAD.Console.PrintWarning("Select something first!\n\n")
596
msg="export VRML from FreeCAD is a python macro that will export simplified VRML of "
597
msg+="a (multi)selected Part or fused Part to VRML optimized to Kicad and compatible with Blender "
598
msg+="the size of VRML is much smaller compared to the one exported from FC Gui "
599
msg+="and the loading/rendering time is also smaller\n"
600
msg+="change mesh deviation to increase quality of VRML\n"
610
#export(objs, fullFilePathName, scale=None)
611
export(objs, fPathName, 0.3937)
612
exportStep(objs, fPathName)
614
def exportStep(objs, ffPathName):
617
exp_name=objs[0].Label
618
path, fname = os.path.split(ffPathName)
619
#fname=os.path.splitext(fname)[0]
620
fullFilePathNameStep=path+os.sep+exp_name+'.step'
622
if os.path.exists(fullFilePathNameStep):
624
QtGui.qApp.restoreOverrideCursor()
625
reply = QtGui.QMessageBox.question(None, "Info", fullFilePathNameStep+"\nstep file exists, overwrite?",
626
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No)
627
if reply == QtGui.QMessageBox.Yes:
628
# this is where the code relevant to a 'Yes' answer goes
631
if reply == QtGui.QMessageBox.No:
632
# this is where the code relevant to a 'No' answer goes
636
ImportGui.export(objs,fullFilePathNameStep)
637
FreeCAD.activeDocument().recompute()
641
home = expanduser("~")
642
#QtGui.QMessageBox.information(None,"info ...","your home path is \r\n"+ home+"\r\n")
643
sayw("kicad StepUp version "+str(___ver___))
644
say("your home path is "+ home+"\r\n")
645
fname_ksu=home+os.sep+'ksu-config.ini'
646
ksu_config_fname=fname_ksu
647
default_ksu_config_ini="""[info]
648
;; kicad StepUp tools config file
649
;; each line starting with a semicolon is a comment
651
;; put here your KISYS3DMOD path or 3D model prefix path
652
;; only ONE prefix is allowed; MUST finish with slash or backslash
653
;prefix3D_1 = C:\\Program Files\\KiCad\share\\kicad\\modules\\packages3d\\
654
;prefix3D_1 = kicad/share/modules/packages3d/
655
prefix3D_1 = C:\\Cad\\Progetti_K\\a_mod\\a_3Dpkg\\
657
;; pcb color r,g,b e.g. 0.0,0.5,0.0,light green
658
;pcb_color=0.3333,0.3333,0.5,blue
659
;pcb_color=0.0,0.5,0.0,light green
660
pcb_color=0.0,0.298,1.0,lightblue (0,76,255)
661
;pcb_color=0.211,0.305,0.455,darkblue (54,79,116)
663
;; put here your model names that you don't want to load (e.g. smallest ones)
664
;; separated by a comma (none means all the models will be parsed)
665
;; (volume=1 means all models with a volume < 1mm3 will not be included)
666
;; (height=1 means all models with a height < 1mm will not be included)
667
;bklist = r_0603,r_0402,c_0402,c_0603
673
;; bounding box option LIST=>whitelist (not converted to bbox)
674
;bbox = LIST dpak-to252,sod80
679
;placement options: useAuxOrigin, useBaseOrigin, useBasePoint;x;y, usedefault, +AutoAdjust
680
;placement = useAuxOrigin
681
;placement = useAuxOrigin +AutoAdjust
682
;placement = useBasePoint;37.0;50.0;
683
;placement = useBasePoint;37.0;50.0; +AutoAdjust
684
;placement = useBaseOrigin #place board @ 0,0,0
685
;placement = useBaseOrigin +AutoAdjust #place board @ 0,0,0
686
;placement = usedefault
687
;placement = usedefault +AutoAdjust
688
placement = useBaseOrigin #place board @ 0,0,0
690
;; virtual modules to be or not added to board
694
;; fuse modules to board
695
;; be careful ... fusion can be heavy or generate FC crash with a lot of objects
696
;; please consider to use bbox or blacklist small objs
697
;exportFusing = fuseAll
698
exportFusing = nofuse #default
700
;; minimum drill size to be handled
701
;; set 0.0 to handle all sizes
704
;; last pcb file path used
706
[last_footprint_path]
707
;; last footprint file path used
712
;export_to_STEP = yes
716
default_ksu_msg.append(""";; kicad StepUp tools config file
717
;; each line starting with a semicolon is a comment""")
718
default_ksu_msg.append(""";; put here your KISYS3DMOD path or 3D model prefix path
719
;; only ONE prefix is allowed; MUST finish with slash or backslash
720
;prefix3D_1 = C:\\Program Files\\KiCad\share\\kicad\\modules\\packages3d\\
721
;prefix3D_1 = kicad/share/modules/packages3d/""")
722
default_ksu_msg.append(""";; pcb color r,g,b e.g. 0.0,0.5,0.0,light green
723
;pcb_color=0.3333,0.3333,0.5,blue
724
;pcb_color=0.0,0.5,0.0,light green
725
;pcb_color=0.0,0.298,1.0,lightblue (0,76,255)
726
;pcb_color=0.211,0.305,0.455,darkblue (54,79,116)""")
727
default_ksu_msg.append(""";; put here your model names that you don't want to load (e.g. smallest ones)
728
;; separated by a comma (none means all the models will be parsed)
729
;; (volume=1 means all models with a volume < 1mm3 will not be included)
730
;; (height=1 means all models with a height < 1mm will not be included)
731
;bklist = r_0603,r_0402,c_0402,c_0603
735
default_ksu_msg.append(""";; bounding box option LIST=>whitelist (not converted to bbox)
736
;bbox = LIST dpak-to252,sod80
738
;bbox = off default""")
739
default_ksu_msg.append(""";; placement options
740
;placement options: useAuxOrigin, useBaseOrigin, useBasePoint;x;y, usedefault, +AutoAdjust
741
;placement = useAuxOrigin
742
;placement = useAuxOrigin +AutoAdjust
743
;placement = useBasePoint;37.0;50.0;
744
;placement = useBasePoint;37.0;50.0; +AutoAdjust
745
;placement = useBaseOrigin #place board @ 0,0,0
746
;placement = useBaseOrigin +AutoAdjust #place board @ 0,0,0
747
;placement = usedefault
748
;placement = usedefault +AutoAdjust""")
749
default_ksu_msg.append(""";; virtual modules to be or not added to board
751
;virt = addVirtual""")
752
default_ksu_msg.append(""";; fuse modules to board
753
;; be careful ... fusion can be heavy or generate FC crash with a lot of objects
754
;; please consider to use bbox or blacklist small objs
755
;exportFusing = fuseAll
756
;exportFusing = nofuse #default""")
757
default_ksu_msg.append(""";; minimum drill size to be processed in mm
758
;; set 0.0 to process all sizes
759
;min_drill_size = 0.0""")
760
default_ksu_msg.append(""";; last pcb file path used
762
default_ksu_msg.append(""";; last footprint file path used
764
default_ksu_msg.append(""";; export to STEP
765
;export_to_STEP = yes
766
;export_to_STEP = no""")
769
if os.path.isfile(ksu_config_fname):
770
say("ksu file \'ksu-config.ini\' exists\r\n")
772
#Kicad_Board_elaborated = open(filename, "r").read()[0:]
773
txtFile = __builtin__.open(ksu_config_fname,"r")
774
ini_content = txtFile.readlines()
775
#ini_content.append(" ")
778
for item in ini_content:
779
if item.startswith("["):
780
data+="<b><font color=GoldenRod>"+item+"</font></b><br>"
781
elif item.startswith(";"):
782
data+="<font color=blue>"+item+"</font><br>"
784
data+="<font color=black>"+item+"</font><br>"
785
#data+=''.join(ini_content)
786
ini_content=re.sub(r'[^\x00-\x7F]+',' ', data)
787
#msg="""<b>kicad StepUp ver. """
788
#msg+=___ver___+"</b><br>"
789
#msg+="default ksu config file created<br>"
790
#msg+="<b>"+fname+"</b>"
791
#reply = QtGui.QMessageBox.information(None,"Info ...",msg)
793
say("ksu file doesn't exist\r\n")
794
say("making default\r\n")
795
with __builtin__.open(ksu_config_fname,'w') as myfile:
796
myfile.write(default_ksu_config_ini)
799
txtFile = __builtin__.open(ksu_config_fname,"r")
800
ini_content = txtFile.readlines()
801
#ini_content.append(" ")
804
data=''.join(ini_content)
805
ini_content=re.sub(r'[^\x00-\x7F]+',' ', data)
806
msg="""<b>kicad StepUp ver. """
807
msg+=___ver___+"</b><br>"
808
msg+="default ksu config file created<br>"
809
msg+="<b>"+ksu_config_fname+"</b>"
810
msg+="<br>adapt your <b>3D model DIR path</b> in config file<br>"
811
msg+="see <b><font color=GoldenRod>[prefix3D]</font></b> section"
812
QtGui.qApp.restoreOverrideCursor()
813
reply = QtGui.QMessageBox.information(None,"Info ...",msg)
817
ini_content=read_ini_file()
818
configParser = ConfigParser.RawConfigParser()
819
configParser = ConfigParser.ConfigParser(allow_no_value = True)
820
configFilePath = ksu_config_fname
821
cfgParsRead(configFilePath)
826
end_milli_time = current_milli_time()
827
running_time=(end_milli_time-start_time)/1000
828
msg="running time: "+str(running_time)+"sec\n"
832
def reset_prop(obj,doc,App,Gui):
833
#say('resetting props\n')
835
newObj =FreeCAD.ActiveDocument.addObject('Part::Feature',obj.Name)
836
newObj.Shape=FreeCAD.ActiveDocument.getObject(obj.Name).Shape
837
FreeCAD.ActiveDocument.ActiveObject.Label=FreeCAD.ActiveDocument.getObject(obj.Name).Label
838
final_Label=FreeCAD.ActiveDocument.getObject(obj.Name).Label
839
#say(final_Label+'\n')
840
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=FreeCADGui.ActiveDocument.getObject(obj.Name).ShapeColor
841
FreeCADGui.ActiveDocument.ActiveObject.LineColor=FreeCADGui.ActiveDocument.getObject(obj.Name).LineColor
842
FreeCADGui.ActiveDocument.ActiveObject.PointColor=FreeCADGui.ActiveDocument.getObject(obj.Name).PointColor
843
FreeCADGui.ActiveDocument.ActiveObject.DiffuseColor=FreeCADGui.ActiveDocument.getObject(obj.Name).DiffuseColor
844
FreeCAD.ActiveDocument.recompute()
845
newObjCommon=FreeCAD.activeDocument().addObject("Part::MultiCommon","Common")
846
newObjCommon.Shapes = [FreeCAD.activeDocument().getObject(obj.Name),FreeCAD.activeDocument().getObject(newObj.Name),]
847
FreeCADGui.activeDocument().getObject(obj.Name).Visibility=False
848
FreeCADGui.activeDocument().getObject(newObj.Name).Visibility=False
849
FreeCADGui.ActiveDocument.Common.ShapeColor=FreeCADGui.ActiveDocument.getObject(obj.Name).ShapeColor
850
FreeCADGui.ActiveDocument.Common.DisplayMode=FreeCADGui.ActiveDocument.getObject(obj.Name).DisplayMode
851
FreeCAD.ActiveDocument.recompute()
853
FreeCAD.ActiveDocument.addObject('Part::Feature','Common').Shape=FreeCAD.ActiveDocument.Common.Shape
854
FreeCAD.ActiveDocument.ActiveObject.Label=final_Label
855
rstObj=FreeCAD.ActiveDocument.ActiveObject
857
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=FreeCADGui.ActiveDocument.Common.ShapeColor
858
FreeCADGui.ActiveDocument.ActiveObject.LineColor=FreeCADGui.ActiveDocument.Common.LineColor
859
FreeCADGui.ActiveDocument.ActiveObject.PointColor=FreeCADGui.ActiveDocument.Common.PointColor
860
FreeCADGui.ActiveDocument.ActiveObject.DiffuseColor=FreeCADGui.ActiveDocument.Common.DiffuseColor
861
FreeCAD.ActiveDocument.removeObject("Common")
862
FreeCAD.ActiveDocument.recompute()
866
def reset_prop_shapes(obj,doc,App,Gui):
869
#say('resetting props #2\n')
872
for i in t.childShapes():
874
c.Placement=t.Placement.multiply(c.Placement)
878
w.Placement=FreeCAD.Placement()
882
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=FreeCADGui.ActiveDocument.Part__Feature.ShapeColor
883
FreeCADGui.ActiveDocument.ActiveObject.LineColor=FreeCADGui.ActiveDocument.Part__Feature.LineColor
884
FreeCADGui.ActiveDocument.ActiveObject.PointColor=FreeCADGui.ActiveDocument.Part__Feature.PointColor
885
FreeCADGui.ActiveDocument.ActiveObject.DiffuseColor=FreeCADGui.ActiveDocument.Part__Feature.DiffuseColor
887
FreeCAD.ActiveDocument.removeObject(obj.Name)
888
FreeCAD.ActiveDocument.recompute()
889
FreeCAD.ActiveDocument.ActiveObject.Label=new_label
890
rstObj=FreeCAD.ActiveDocument.ActiveObject
897
def Display_info(blacklisted_models):
898
global bbox_all, bbox_list, fusion, show_messages, last_pcb_path
899
global height_minimum, volume_minimum, idf_to_origin, ksu_config_fname
900
global board_base_point_x, board_base_point_y, real_board_pos_x, real_board_pos_y
901
say('info message\n')
902
if blacklisted_model_elements != '':
903
sayw("black-listed module "+ '\r\n'.join(map(str, blacklisted_models)))
904
if (show_messages==True):
905
QtGui.qApp.restoreOverrideCursor()
906
reply = QtGui.QMessageBox.information(None,"Info ...","... black-listed module(s)\r\n"+ '\r\n'.join(map(str, blacklisted_models)))
907
#FreeCAD.Console.PrintMessage("black-listed module "+ '\r\n'.join(map(str, blacklisted_models)))
909
msg="""<b>kicad StepUp</b> ver. """
912
# insert_return(msgpath, 15)
913
if (idf_to_origin==True):
914
new_pos_x=board_base_point_x+real_board_pos_x
915
new_pos_y=board_base_point_y+real_board_pos_y
917
new_pos_x=board_base_point_x
918
new_pos_y=board_base_point_y
919
msg+="<br>Board Placed @ "+str(new_pos_x)+";"+str(new_pos_y)+";0.0"
920
msg+="<br>kicad pcb pos: ("+"{0:.3f}".format(real_board_pos_x)+";"+"{0:.3f}".format(real_board_pos_y)+";"+"{0:.2f}".format(0)+")"
921
if (bbox_all==1) or (bbox_list==1):
922
msg+="<br>bounding box modules applied"
923
if (volume_minimum!=0):
924
msg+="<br>modules with volume less then "+str(volume_minimum)+"mm^3 not included"
925
if (height_minimum!=0):
926
msg+="<br>modules with height less then "+str(height_minimum)+"mm not included"
927
msg+="<br>kicad StepUp config file in:<br><b>"+ksu_config_fname+"</b><br>location."
928
say("Board Placed @ "+str(new_pos_x)+";"+str(new_pos_y)+";0.0\n")
929
say("kicad pcb pos: ("+"{0:.3f}".format(real_board_pos_x)+";"+"{0:.3f}".format(real_board_pos_y)+";"+"{0:.2f}".format(0)+")\n")
930
if (show_messages==True):
931
QtGui.qApp.restoreOverrideCursor()
932
reply = QtGui.QMessageBox.information(None,"Info ...",msg)
935
def Export2MCAD(blacklisted_model_elements):
936
global bbox_all, bbox_list, fusion, show_messages, last_pcb_path
937
global height_minimum, volume_minimum, idf_to_origin, ksu_config_fname
938
global board_base_point_x, board_base_point_y, real_board_pos_x, real_board_pos_y
939
say('exporting to MCAD\n')
942
doc=FreeCAD.ActiveDocument
943
for obj in doc.Objects:
944
# do what you want to automate
945
if (obj.Label!="Board_Geoms") and (obj.Label!="Step_Models"):
946
FreeCADGui.Selection.addSelection(obj)
948
filePath=last_pcb_path
949
if (bbox_all==1) or (bbox_list==1):
950
fpath=filePath+os.sep+doc.Label+"_bbox"+'.step'
952
fpath=filePath+os.sep+doc.Label+'.step'
953
ImportGui.export(__objs__,fpath)
955
## be careful ... fusion can be heavy or generate FC crash with a lot of objects
956
## please consider to use bbox or blacklist small objs
959
doc.addObject("Part::MultiFuse","Fusion")
960
doc.Fusion.Shapes = __objs__
961
# doc.ActiveObject.Label=doc.Name+"_union"
963
doc.addObject('Part::Feature','Fusion').Shape=FreeCAD.ActiveDocument.Fusion.Shape
964
if (bbox_all==1) or (bbox_list==1):
965
doc.ActiveObject.Label=doc.Name+"_bbox_union"
967
doc.ActiveObject.Label=doc.Name+"_union"
968
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=FreeCADGui.ActiveDocument.Fusion.ShapeColor
969
FreeCADGui.ActiveDocument.ActiveObject.LineColor=FreeCADGui.ActiveDocument.Fusion.LineColor
970
FreeCADGui.ActiveDocument.ActiveObject.PointColor=FreeCADGui.ActiveDocument.Fusion.PointColor
971
FreeCADGui.ActiveDocument.ActiveObject.DiffuseColor=FreeCADGui.ActiveDocument.Fusion.DiffuseColor
972
# Remove the fusion object
973
doc.removeObject("Fusion")
976
fused_obj=doc.ActiveObject
977
FreeCAD.Console.PrintMessage(fused_obj)
978
fobjs.append(fused_obj)
979
if (bbox_all==1) or (bbox_list==1):
980
fpath=filePath+os.sep+doc.Label+"_bbox_union"+'.step'
982
fpath=filePath+os.sep+doc.Label+"_union"+'.step'
983
FreeCAD.Console.PrintMessage(fpath+" fusion path \r\n")
984
FreeCAD.Console.PrintMessage(fobjs)
986
ImportGui.export(fobjs,fpath)
987
FreeCAD.activeDocument().recompute()
989
#ImportGui.export(doc.ActiveObject,filePath+os.sep+doc.Label+'.step')
990
for obj in doc.Objects:
991
# do what you want to automate
992
FreeCADGui.Selection.removeSelection(obj)
993
if blacklisted_model_elements != '':
994
sayw("black-listed module "+ '\r\n'.join(map(str, blacklisted_models)))
995
if (show_messages==True):
996
QtGui.qApp.restoreOverrideCursor()
997
reply = QtGui.QMessageBox.information(None,"Info ...","... black-listed module(s)\r\n"+ '\r\n'.join(map(str, blacklisted_models)))
998
#FreeCAD.Console.PrintMessage("black-listed module "+ '\r\n'.join(map(str, blacklisted_models)))
1000
## Save to disk in native format
1001
FreeCAD.ActiveDocument=None
1002
FreeCADGui.ActiveDocument=None
1003
FreeCAD.setActiveDocument(doc.Name)
1004
FreeCAD.ActiveDocument=FreeCAD.getDocument(doc.Name)
1005
FreeCADGui.ActiveDocument=FreeCADGui.getDocument(doc.Name)
1006
if (bbox_all==1) or (bbox_list==1):
1007
fpath=filePath+os.sep+doc.Name+"_bbox"
1009
fpath=filePath+os.sep+doc.Name
1011
fpath=fpath+"_union"
1012
say(fpath+".FCStd"+"\n")
1013
FreeCAD.getDocument(doc.Name).saveAs(fpath+".FCStd")
1014
FreeCAD.ActiveDocument.recompute()
1015
FreeCAD.getDocument(doc.Name).Label = doc.Name
1016
FreeCADGui.SendMsgToActiveView("Save")
1017
FreeCAD.getDocument(doc.Name).save()
1018
msgpath=filePath+os.sep+doc.Name
1019
if (bbox_all==1) or (bbox_list==1):
1020
msgpath=msgpath+"_bbox"
1022
msg="""<b>kicad StepUp</b> ver. """
1024
msg+="<br>file exported<br><b>"+msgpath+'.step</b>'
1025
#if len(msgpath)>15:
1026
# insert_return(msgpath, 15)
1028
msgpath=msgpath+"_union"
1029
msg+="<br>fused file exported<br><b>"+msgpath+'.step</b>'
1030
if (idf_to_origin==True):
1031
new_pos_x=board_base_point_x+real_board_pos_x
1032
new_pos_y=board_base_point_y+real_board_pos_y
1034
new_pos_x=board_base_point_x
1035
new_pos_y=board_base_point_y
1036
msg+="<br>Board Placed @ "+str(new_pos_x)+";"+str(new_pos_y)+";0.0"
1037
msg+="<br>kicad pcb pos: ("+"{0:.3f}".format(real_board_pos_x)+";"+"{0:.3f}".format(real_board_pos_y)+";"+"{0:.2f}".format(0)+")"
1038
if (bbox_all==1) or (bbox_list==1):
1039
msg+="<br>bounding box modules applied"
1040
if (volume_minimum!=0):
1041
msg+="<br>modules with volume less then "+str(volume_minimum)+"mm^3 not included"
1042
if (height_minimum!=0):
1043
msg+="<br>modules with height less then "+str(height_minimum)+"mm not included"
1044
msg+="<br>kicad StepUp config file in:<br><b>"+ksu_config_fname+"</b><br>location."
1045
say("Board Placed @ "+str(new_pos_x)+";"+str(new_pos_y)+";0.0\n")
1046
say("kicad pcb pos: ("+"{0:.3f}".format(real_board_pos_x)+";"+"{0:.3f}".format(real_board_pos_y)+";"+"{0:.2f}".format(0)+")\n")
1047
if (show_messages==True):
1048
QtGui.qApp.restoreOverrideCursor()
1049
reply = QtGui.QMessageBox.information(None,"Info ...",msg)
1052
def Load_models(pcbThickness,modules):
1053
global off_x, off_y, volume_minimum, height_minimum, bbox_all, bbox_list
1054
global whitelisted_model_elements, models3D_prefix, last_pcb_path
1057
for i in range(len(modules)):
1058
step_module=modules[i][0]
1059
#say(modules[i]);say('\n')
1060
#FreeCAD.Console.PrintMessage('step-module '+step_module+'\r\n')
1061
if (step_module.find('${KIPRJMOD}')!=-1): #local 3D path
1062
#step_module=step_module.replace('${KIPRJMOD}', '.')
1063
step_module=step_module.replace('${KIPRJMOD}', last_pcb_path)
1064
say('adjusting Local Path\r\n')
1065
say('step-module-replaced '+step_module+'\n')
1066
if step_module != 'no3Dmodel':
1067
step_module=step_module[:-3]+'step'
1068
step_module2=step_module[:-4]+'stp'
1069
step_module3=step_module[:-4]+'iges'
1070
step_module4=step_module[:-4]+'igs'
1071
model_name=step_module[:-5]
1072
last_slash_pos1=model_name.rfind('/')
1073
last_slash_pos2=model_name.rfind('\\')
1074
last_slash_pos=max(last_slash_pos1,last_slash_pos2)
1075
model_name=model_name[last_slash_pos+1:]
1076
say('model name '+model_name+'\n')
1078
model_name='no3Dmodel'
1080
if blacklisted_model_elements != '':
1081
if blacklisted_model_elements.find(model_name) != -1:
1084
if (blacklisted==0):
1085
if step_module != 'no3Dmodel':
1086
module_path='not-found'
1087
step_module=step_module.replace('"', '') # name with spaces
1088
if os.path.exists(models3D_prefix+step_module):
1089
module_path=models3D_prefix+step_module
1091
if os.path.exists(step_module): # absolute path
1092
module_path=step_module
1093
#adding .stp support
1094
if os.path.exists(models3D_prefix+step_module2) and (module_path=='not-found'):
1095
module_path=models3D_prefix+step_module2
1097
if os.path.exists(step_module2) and (module_path=='not-found'): # absolute path
1098
module_path=step_module2
1099
#adding .iges support
1100
if os.path.exists(models3D_prefix+step_module3) and (module_path=='not-found'):
1101
module_path=models3D_prefix+step_module3
1103
if os.path.exists(step_module3) and (module_path=='not-found'): # absolute path
1104
module_path=step_module3
1105
#adding .igs support
1106
if os.path.exists(models3D_prefix+step_module4) and (module_path=='not-found'):
1107
module_path=models3D_prefix+step_module4
1109
if os.path.exists(step_module4) and (module_path=='not-found'): # absolute path
1110
module_path=step_module4
1111
if module_path!='not-found':
1112
#FreeCADGui.Selection.removeSelection(FreeCAD.activeDocument().ActiveObject) mauitemp volume diff
1113
say("opening "+ module_path+'\n')
1114
ImportGui.insert(module_path,FreeCAD.ActiveDocument.Name)
1115
if FreeCAD.ActiveDocument.ActiveObject.Label.endswith('001'):
1116
msg="""3D STEP model <b><font color=red>"""
1117
msg+=model_name+"</font> is NOT fused in a single part</b> ...<br>"
1118
msg+="@ "+module_path+" <br>...stopping execution! <br>Please <b>fix</b> the model."
1119
QtGui.qApp.restoreOverrideCursor()
1120
reply = QtGui.QMessageBox.information(None,"Info ...",msg)
1123
pos_x=modules[i][1]-off_x
1124
pos_y=modules[i][2]-off_y
1126
step_layer=modules[i][4]
1128
impPart=FreeCAD.ActiveDocument.ActiveObject
1129
say("module "+step_module+"\n")
1130
impPart.Label = impPart.Label + '_'
1131
#say("selection 3D model "+ impPart.Label+'\n')
1132
impPart=reset_prop_shapes(impPart,FreeCAD.ActiveDocument, FreeCAD,FreeCADGui)
1133
model3D=impPart.Name
1134
#say("impPart "+ impPart.Name+'\n')
1135
obj = FreeCAD.ActiveDocument.getObject(model3D)
1136
FreeCADGui.Selection.addSelection(obj)
1137
obj=FreeCAD.ActiveDocument.ActiveObject
1139
myPart=FreeCAD.ActiveDocument.getObject(obj.Name) #mauitemp min vol
1142
#sayw(str(myPart.Shape.Volume))
1143
#sayw(str(myPart.Shape.BoundBox.ZMax))
1144
if myPart.Shape.Volume>volume_minimum: #mauitemp min vol
1145
if abs(myPart.Shape.BoundBox.ZMax)>height_minimum: #mauitemp min height
1146
if (height_minimum!=0):
1147
say("height > Min height "+ str(myPart.Shape.BoundBox.ZMax) + " "+impPart.Label+'\r\n')
1148
if (volume_minimum!=0):
1149
say("Volume > Min Volume "+ str(myPart.Shape.Volume) + " "+impPart.Label+'\r\n')
1150
if (bbox_all==1) or (bbox_list==1):
1151
if whitelisted_model_elements.find(model_name) == -1:
1152
bboxName=createSolidBBox(model3D)
1153
#say(str(bbox_all)+'bbox'+str(bbox_list)+'\n')
1155
if step_layer == 'Top':
1156
impPart.Placement = FreeCAD.Placement(FreeCAD.Vector(pos_x,pos_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),rot))
1157
if (bbox_all==1) or (bbox_list==1):
1159
if whitelisted_model_elements.find(model_name) == -1:
1160
bbox_col=bbox_default_col
1161
#say("bboxName "+ bboxName +'\r\n')
1162
#say("bboxName "+str(bboxName.upper().startswith('R'))+'\r\n')
1163
if (bboxName.upper().startswith('X')):
1165
if (bboxName.upper().startswith('L')):
1167
if (bboxName.upper().startswith('R')):
1169
if (bboxName.upper().startswith('C')):
1171
if (bboxName.upper().startswith('S')|bboxName.upper().startswith('Q')|bboxName.upper().startswith('D')|bboxName.upper().startswith('T')):
1172
bbox_col=bbox_IC_col
1173
obj = FreeCAD.ActiveDocument.getObject(bboxName)
1174
obj.Placement = FreeCAD.Placement(FreeCAD.Vector(pos_x,pos_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),rot))
1175
FreeCADGui.ActiveDocument.getObject(bboxName).ShapeColor=bbox_col
1176
FreeCADGui.Selection.addSelection(obj)
1177
#say("selection 3D model "+ obj.Name+'\r\n')
1178
FreeCAD.ActiveDocument.getObject("Step_Models").addObject(obj)
1179
FreeCADGui.Selection.addSelection(impPart)
1180
FreeCAD.ActiveDocument.getObject("Step_Models").addObject(impPart)
1181
if (bbox_all==1) or (bbox_list==1):
1182
if whitelisted_model_elements.find(model_name) == -1:
1183
FreeCAD.activeDocument().removeObject(impPart.Name)
1184
#FreeCAD.activeDocument().removeObject(impPart.Name)
1189
impPart.Placement = FreeCAD.Placement(FreeCAD.Vector(pos_x,pos_y,-pcbThickness),FreeCAD.Rotation(FreeCAD.Vector(0,1,0),180))
1190
#obj.Placement = impPart.Placement
1191
shape=impPart.Shape.copy()
1192
shape.Placement=impPart.Placement;
1193
shape.rotate((pos_x,pos_y,-pcbThickness),(0,0,1),-rot+180)
1194
impPart.Placement=shape.Placement
1195
if (bbox_all==1) or (bbox_list==1):
1196
if whitelisted_model_elements.find(model_name) == -1:
1197
bbox_col=bbox_default_col
1198
if (bboxName.upper().startswith('X')):
1200
if (bboxName.upper().startswith('L')):
1202
if (bboxName.upper().startswith('R')):
1204
if (bboxName.upper().startswith('C')):
1206
if (bboxName.upper().startswith('S')|bboxName.upper().startswith('Q')|bboxName.upper().startswith('D')|bboxName.upper().startswith('T')):
1207
bbox_col=bbox_IC_col
1208
obj = FreeCAD.ActiveDocument.getObject(bboxName)
1209
FreeCADGui.Selection.addSelection(obj)
1210
obj.Placement = FreeCAD.Placement(FreeCAD.Vector(pos_x,pos_y,-pcbThickness),FreeCAD.Rotation(FreeCAD.Vector(0,1,0),180))
1211
shape2=obj.Shape.copy()
1212
shape2.Placement=obj.Placement;
1213
shape2.rotate((pos_x,pos_y,-pcbThickness),(0,0,1),-rot+180)
1214
obj.Placement=shape2.Placement
1215
FreeCADGui.ActiveDocument.getObject(bboxName).ShapeColor=bbox_col
1216
FreeCADGui.Selection.addSelection(obj)
1217
FreeCAD.ActiveDocument.getObject(obj.Name)
1218
FreeCAD.ActiveDocument.getObject("Step_Models").addObject(obj)
1219
FreeCADGui.Selection.addSelection(impPart)
1220
FreeCAD.ActiveDocument.getObject(impPart.Name)
1221
FreeCAD.ActiveDocument.getObject("Step_Models").addObject(impPart)
1222
if (bbox_all==1) or (bbox_list==1):
1223
if whitelisted_model_elements.find(model_name) == -1:
1224
FreeCAD.activeDocument().removeObject(impPart.Name)
1228
else: #mauitemp min height
1229
FreeCAD.activeDocument().removeObject(obj.Name)
1230
else: #mauitemp min vol
1231
FreeCAD.activeDocument().removeObject(obj.Name)
1234
say("error missing "+ models3D_prefix+step_module+'\r\n')
1235
test = missing_models.find(step_module)
1237
missing_models += models3D_prefix+step_module+'\r\n' #matched
1242
FreeCAD.ActiveDocument.recompute()
1243
if missing_models != '':
1244
QtGui.qApp.restoreOverrideCursor()
1245
reply = QtGui.QMessageBox.information(None,"Error ...","... missing module(s)\r\n"+ missing_models)
1246
#if blacklisted_model_elements != '':
1247
# FreeCAD.Console.PrintMessage("black-listed module "+ '\n'.join(map(str, blacklisted_models)))
1248
# reply = QtGui.QMessageBox.information(None,"Info ...","... black-listed module(s)\n"+ '\n'.join(map(str, blacklisted_models)))
1249
# #FreeCAD.Console.PrintMessage("black-listed module "+ '\n'.join(map(str, blacklisted_models)))
1250
return blacklisted_model_elements
1254
def LoadKicadBoard (board_fname):
1255
# checking FC version requirement
1256
######################################################################
1257
#say("FC Version \r\n")
1258
#say(FreeCAD.Version())
1259
global start_time, fusion
1260
FC_majorV=FreeCAD.Version()[0]
1261
FC_minorV=FreeCAD.Version()[1]
1262
say('FC Version '+FC_majorV+FC_minorV+'\r\n')
1263
msg1="use ONLY FreeCAD STABLE version 0.15 or later\r\n"
1264
#msg1+="to generate your STEP and VRML models\r\nFC 016 dev version results are still unpredictable"
1265
msg1+="to generate your STEP and VRML models\r\n"
1266
if int(FC_majorV) <= 0:
1267
if int(FC_minorV) < 15:
1268
QtGui.qApp.restoreOverrideCursor()
1269
reply = QtGui.QMessageBox.information(None,"Warning! ...",msg1)
1272
msg+="you have chosen: fuse modules to board\r\nbe careful ... fusion can be heavy or generate FC crash"
1273
msg+="when fusing a lot of objects\r\nplease consider to use bbox or blacklist small objects\r\n\r\n"
1274
##start_time=current_milli_time()
1275
xMax=0; xmin=0; yMax=0; ymin=0
1277
Edge_Cuts_lvl=0;Top_lvl=0
1278
Kicad_Board_elaborated,Levels,Edge_Cuts_lvl,Top_lvl,PCBVersion,pcbThickness = Elaborate_Kicad_Board(board_fname)
1279
say('PCBThickness'+str(pcbThickness)+' mm\n')
1281
#sayw(str(Top_lvl)+' top_lvl')
1283
modules = getParts(modules,Top_lvl,Kicad_Board_elaborated,Levels)
1285
#for i in range(len(modules)):
1286
# for j in range(len(modules[i])):
1287
# #print len(modules[i])
1288
# print modules[i][j]
1289
return pcbThickness,modules,Kicad_Board_elaborated
1290
### end LoadKicadBoard
1292
def getPads(board_elab,pcbThickness):
1298
for module in re.findall(r'\[start\]\(module(.+?)\)\[stop\]', board_elab, re.MULTILINE|re.DOTALL):
1299
[X1, Y1, ROT] = re.search(r'\(at\s+([0-9\.-]*?)\s+([0-9\.-]*?)(\s+[0-9\.-]*?|)\)', module).groups()
1302
Y1 = float(Y1) * (-1)
1307
#say('module pos & rot '+str(X1)+' '+str(Y1)+' '+str(ROT)+'\n')
1309
for pad in getPadsList(module):
1311
# pads.append({'x': x, 'y': y, 'rot': rot, 'padType': pType, 'padShape': pShape, 'rx': drill_x, 'ry': drill_y, 'dx': dx, 'dy': dy, 'holeType': hType, 'xOF': xOF, 'yOF': yOF, 'layers': layers})
1312
pType = pad['padType']
1313
pShape = pad['padShape']
1318
hType = pad['holeType']
1330
numberOfLayers = pad['layers'].split(' ')
1331
#if pType=="thru_hole":
1332
#pad shape - circle/rec/oval/trapezoid
1334
if pShape=="circle" or pShape=="oval":
1337
# pad type - SMD/thru_hole/connect
1340
#say(str(dx)+"+"+str(rx)+" dx,rx\r\n")
1341
#say(str(dy)+"+"+str(ry)+" dy,ry\r\n")
1342
#say(str(xOF)+"+"+str(yOF)+" xOF,yOF\r\n")
1344
y1=ys-yOF #yoffset opposite
1345
#say(str(x1)+"+"+str(y1)+" x1,y1\r\n")
1348
if 'F.Cu' in numberOfLayers:
1350
if '*.Cu' in numberOfLayers:
1353
if 'B.Cu' in numberOfLayers:
1356
#say(str(min_drill_size));say(' ');say(rx);say(' ');say(str(ry));say('\n')
1357
if (rx >= min_drill_size) or (ry >= min_drill_size):
1358
obj=createHole3(xs,ys,rx,ry,"oval",pcbThickness) #need to be separated instructions
1361
rotateObj(obj, [xs, ys, rot])
1362
rotateObj(obj, [X1, Y1, ROT])
1363
HoleList.append(obj)
1364
### cmt- #todo: pad type trapez
1367
def getPads_flat(board_elab):
1373
for module in re.findall(r'\[start\]\(module(.+?)\)\[stop\]', board_elab, re.MULTILINE|re.DOTALL):
1374
[X1, Y1, ROT] = re.search(r'\(at\s+([0-9\.-]*?)\s+([0-9\.-]*?)(\s+[0-9\.-]*?|)\)', module).groups()
1377
Y1 = float(Y1) * (-1)
1382
#say('module pos & rot '+str(X1)+' '+str(Y1)+' '+str(ROT)+'\n')
1384
for pad in getPadsList(module):
1387
# pads.append({'x': x, 'y': y, 'rot': rot, 'padType': pType, 'padShape': pShape, 'rx': drill_x, 'ry': drill_y, 'dx': dx, 'dy': dy, 'holeType': hType, 'xOF': xOF, 'yOF': yOF, 'layers': layers})
1388
pType = pad['padType']
1389
pShape = pad['padShape']
1394
hType = pad['holeType']
1406
numberOfLayers = pad['layers'].split(' ')
1407
#say(numberOfLayers +'\n')
1408
#if pType=="thru_hole":
1409
#pad shape - circle/rec/oval/trapezoid
1411
if pShape=="circle" or pShape=="oval":
1414
# pad type - SMD/thru_hole/connect
1417
#say(str(dx)+"+"+str(rx)+" dx,rx\r\n")
1418
#say(str(dy)+"+"+str(ry)+" dy,ry\r\n")
1419
#say(str(xOF)+"+"+str(yOF)+" xOF,yOF\r\n")
1421
y1=ys-yOF #yoffset opposite
1422
#say(str(x1)+"+"+str(y1)+" x1,y1\r\n")
1425
if 'F.Cu' in numberOfLayers:
1427
if '*.Cu' in numberOfLayers:
1430
if 'B.Cu' in numberOfLayers:
1433
#say(str(min_drill_size));say(' ');say(rx);say(' ');say(str(ry));say('\n')
1434
#if (rx > min_drill_size):
1435
if (rx >= min_drill_size) or (ry >= min_drill_size):
1436
#obj=createHole3(xs,ys,rx,ry,"oval",pcbThickness) #need to be separated instructions
1437
obj=createHole4(xs,ys,rx,ry,"oval") #need to be separated instructions
1440
rotateObj(obj, [xs, ys, rot])
1441
rotateObj(obj, [X1, Y1, ROT])
1442
HoleList.append(obj)
1443
### cmt- #todo: pad type trapez
1447
def Elaborate_Kicad_Board(filename):
1448
global xMax, xmin, yMax, ymin
1451
txtFile = __builtin__.open(filename,"r")
1452
content = txtFile.readlines()
1455
data=''.join(content)
1456
content=re.sub(r'[^\x00-\x7F]+',' ', data)
1458
Kicad_Board_elaborated = content #''.join(content)
1460
home = expanduser("~")
1461
t1_name=home+os.sep+'test.txt'
1462
f = __builtin__.open(t1_name,'w')
1463
f.write(Kicad_Board_elaborated) # python will convert \n to os.linesep
1464
f.close() # you can omit in most cases as the destructor will call it
1465
#say(len(Kicad_Board_elaborated))
1467
version=getPCBVersion(Kicad_Board_elaborated)
1468
pcbThickness=getPCBThickness(Kicad_Board_elaborated)
1469
say('kicad_pcb version ' +str(version)+'\n')
1471
QtGui.qApp.restoreOverrideCursor()
1472
reply = QtGui.QMessageBox.information(None,"Error ...","... KICAD pcb version "+ str(version)+" not supported \r\n"+"\r\nplease open and save your board with the latest kicad version")
1473
sys.exit("pcb version not supported")
1482
j = 0; txt = ''; start = 0; s=0; prev_char="_"
1484
#print len(Kicad_Board_elaborated)
1485
for i in Kicad_Board_elaborated[1:]:
1486
if i in ['"', "'"] and s == 0:
1490
elif i in [closing_char] and s == 1:
1501
if j == 0 and start == 1:
1502
modified += '[start]' + txt.strip() + '[stop]'
1507
layers = re.search(r'\[start\]\(layers(.+?)\)\[stop\]', modified, re.MULTILINE|re.DOTALL).group(0)
1508
for k in re.findall(r'\((.*?) (.*?) .*?\)', layers):
1509
Levels[k[1]] = int(k[0])
1510
if Levels[k[1]] == Edge_Cuts_lvl: ##Edge.Cuts pcb version 4
1511
#myfile3.write(str(k)[8:-2]+'\r\n')
1512
pcbEdgeName=str(k)[8:-2]
1514
home = expanduser("~")
1515
t2_name=home+os.sep+'testM.txt'
1516
f = __builtin__.open(t2_name,'w')
1517
f.write(modified) # python will convert \n to os.linesep
1518
f.close() # you can omit in most cases as the destructor will call it
1519
return modified,Levels,Edge_Cuts_lvl,Top_lvl,version,pcbThickness
1520
### end Elaborate_Kicad_Board
1522
def getParts(PCB_Models,Top_lvl,Kicad_Board_elaborated,Levels):
1525
for i in re.findall(r'\[start\]\(module(.+?)\)\[stop\]', Kicad_Board_elaborated, re.MULTILINE|re.DOTALL):
1527
[x, y, rot] = re.search(r'\(at\s+([0-9\.-]*?)\s+([0-9\.-]*?)(\s+[0-9\.-]*?|)\)', i).groups()
1528
layer = re.search(r'\(layer\s+(.+?)\)', i).groups()[0]
1535
#rot=rot-rotz #adding vrml module z-rotation
1537
if Levels[layer] == Top_lvl: # top
1542
#model = re.search(r'\(model\s+(.+?)\.wrl',i)
1543
model_name='no3Dmodel'
1545
model_list= re.findall(r'\(model\s+(.+?)\.wrl',i)
1546
for j in range(0,len(model_list)):
1547
rotz_vrml = re.findall(r'\(rotate\s+(.+?)\)', i)
1551
#say("rotz:"+rotz+"\r\n")
1554
#say("rotz:"+rotz+"\r\n")
1555
temp=rotz.split(" ")
1556
#say("rotz temp:"+temp[2]+"\r\n")
1558
#say("rotate vrml: "+rotz+"\r\n")
1563
rot=rot-rotz #adding vrml module z-rotation
1564
model=model_list[j]+'.wrl'
1566
#virtual = re.search(r'\(attr\s+(.+?)virtual\)',i)
1568
if (i.find("virtual")!=-1):
1570
if (virtual==1 and addVirtual==0):
1571
model_name='no3Dmodel'
1575
# print model.group(0)
1576
#model_name=model.group(0)[6:]
1577
#model_name=model[6:]
1579
#model_name=model_name[1:]
1582
model_name='no3Dmodel'
1585
line.append(model_name)
1590
PCB_Models.append(line)
1591
##virtual = re.search(r'\(attr\s+(.+?)virtual\)',i)
1598
def getPCBThickness(Board):
1599
#print len(Kicad_Board)
1600
return float(re.findall(r'\(thickness (.+?)\)', Board)[0])
1602
def getPCBVersion(Board):
1603
return int(re.findall(r'\(kicad_pcb \(version (.+?)\)', Board)[0])
1605
def getPCBArea(Kicad_Board):
1606
area = (re.findall(r'\(area (.+?)\)', Kicad_Board)[0])
1610
def createSolidBBox(model3D):
1612
selEx = FreeCADGui.Selection.getSelectionEx()
1613
objs = [selobj.Object for selobj in selEx]
1617
FreeCAD.Console.PrintMessage(name+" name \r\n")
1619
boundBox_ = s.BoundBox
1620
boundBoxLX = boundBox_.XLength
1621
boundBoxLY = boundBox_.YLength
1622
boundBoxLZ = boundBox_.ZLength
1626
oripl_X = float(c[0])
1627
oripl_Y = float(c[1])
1628
oripl_Z = float(c[2])
1629
#say(str(boundBox_)+"\r\n")
1630
#say("Rectangle : "+str(boundBox_.XLength)+" x "+str(boundBox_.YLength)+" x "+str(boundBox_.ZLength)+"\r\n")
1631
#say("_____________________"+"\r\n")
1632
#say("x: "+str(oripl_X)+" y: "+str(oripl_Y)+"z: "+str(oripl_Z)+"\r\n")
1633
obj=FreeCAD.ActiveDocument.addObject('Part::Feature',name)
1634
obj.Shape=Part.makeBox(boundBox_.XLength, boundBox_.YLength, boundBox_.ZLength, FreeCAD.Vector(oripl_X,oripl_Y,oripl_Z), FreeCAD.Vector(0,0,01))
1636
#say("cube name "+ obj.Name+'\r\n')
1638
FreeCAD.Console.PrintMessage("Select a single part object !"+"\r\n")
1641
#say("bbox name "+name+"\n")
1644
### end createSolidBBox
1646
def findPcbCenter(pcbName):
1647
pcb = FreeCAD.ActiveDocument.getObject(pcbName)
1651
boundBox_ = s.BoundBox
1652
boundBoxLX = boundBox_.XLength
1653
boundBoxLY = boundBox_.YLength
1654
boundBoxLZ = boundBox_.ZLength
1655
center = s.BoundBox.Center
1657
#say("["+str(center.x)+"],["+str(center.y)+"] center of pcb\r\n")
1661
oripl_X = float(c[0])
1662
oripl_Y = float(c[1])
1663
oripl_Z = float(c[2])
1664
#say(str(boundBox_)+"\r\n")
1665
#say("Rectangle : "+str(boundBox_.XLength)+" x "+str(boundBox_.YLength)+" x "+str(boundBox_.ZLength)+"\r\n")
1666
#say("_____________________"+"\r\n")
1667
#say("x: "+str(oripl_X)+" y: "+str(oripl_Y)+"z: "+str(oripl_Z)+"\r\n")
1668
center_x=center.x; center_y=center.y
1669
bb_x=boundBox_.XLength; bb_y=boundBox_.YLength
1670
return center_x, center_y, bb_x, bb_y
1671
### end findPcbCenter
1673
def getArc_minMax(xC,xA,yC,yA,alpha):
1674
# x1=xA start point; x2=xC center; xB end point; alpha=angle
1675
global xMax, xmin, yMax, ymin
1677
R=sqrt((xA-xC)**2+(yA-yC)**2)
1679
if (xA>=xC) and (yA<yC):
1680
beta=atan(abs(xA-xC)/abs(yA-yC))
1681
j=1; ABeta=(alpha+beta)
1682
#say(str(degrees(beta))+" beta "+ str(degrees(ABeta))+" ABeta\r\n")
1683
#cases if (xA>xC) and (yA<yC):
1684
if ABeta >= beta and ABeta <= pi/2:
1685
xB=R*sin(alpha+beta)+xC
1688
yB=yC-R*cos(alpha+beta)
1691
if ABeta >pi/2 and ABeta <=pi:
1692
xMax = max(R+xC,xMax)
1693
xB=R*sin(alpha+beta)+xC
1694
xmin = min(xA, xB, xmin)
1695
# yB = yC+R*cos(pi-(alpha+beta))
1696
yB=yC-R*cos(alpha+beta)
1697
yMax = max(yB, yMax)
1698
ymin = min(yA, ymin)
1699
if ABeta >pi and ABeta <=3/2*pi:
1700
xB=R*sin(alpha+beta)+xC
1703
yB=yC-R*cos(alpha+beta)
1704
yMax = max(yC+R, yMax)
1705
ymin = min(yA, ymin)
1706
if ABeta >3/2*pi and ABeta <= 2*pi:
1707
xB=R*sin(alpha+beta)+xC
1709
xmin = min(xC-R,xmin)
1710
yB=yC-R*cos(alpha+beta)
1711
yMax = max(yC+R, yMax)
1712
ymin = min(yA, yB, ymin)
1713
if ABeta >2*pi and ABeta <= 2*pi+beta:
1714
xmin = min(xC-R,xmin)
1715
xMax = max(R+xC,xMax)
1716
ymin = min(yC-R, ymin)
1717
yMax = max(yC+R, yMax)
1718
if (xA>xC) and (yA>=yC):
1719
beta=atan(abs(yA-yC)/abs(xA-xC))
1720
j=2; ABeta=(alpha+beta)
1721
#say(str(degrees(beta))+" beta "+ str(degrees(ABeta))+" ABeta\r\n")
1724
if ABeta >= beta and ABeta <= pi/2:
1729
if ABeta > pi/2 and ABeta <= pi:
1732
ymin= min(yA, yB, ymin)
1733
yMax= max(yC+R, yMax)
1734
if ABeta > pi and ABeta <= 3/2*pi:
1735
xmin= min(xC-R,xmin)
1738
yMax= max(yC+R, yMax)
1739
if ABeta > 3/2*pi and ABeta <= 2*pi:
1740
xmin= min(xC-R,xmin)
1741
xMax= max(xA,xB,xMax)
1742
ymin= min(yC-R, ymin)
1743
yMax= max(yC+R, yMax)
1744
if ABeta > 2*pi and ABeta <= beta+2*pi:
1745
xmin= min(xC-R,xmin)
1746
xMax= max(xC+R,xMax)
1747
ymin= min(yC-R, ymin)
1748
yMax= max(yC+R, yMax)
1749
if (xA<=xC) and (yA>yC):
1750
beta=atan(abs(xA-xC)/abs(yA-yC))
1751
j=3; ABeta=(alpha+beta)
1752
#say(str(degrees(beta))+" beta "+ str(degrees(ABeta))+" ABeta\r\n")
1755
if ABeta >= beta and ABeta <= pi/2:
1760
if ABeta > pi/2 and ABeta <= pi:
1761
xmin= min(xC-R,xmin)
1762
xMax= max(xA,xB,xMax)
1765
if ABeta > pi and ABeta <= 3/2*pi:
1766
xmin= min(xC-R,xmin)
1768
ymin= min(yC-R, ymin)
1770
if ABeta > 3/2*pi and ABeta <= 2*pi:
1771
xmin= min(xC-R,xmin)
1772
xMax= max(xC+R,xMax)
1773
ymin= min(yC-R, ymin)
1774
yMax= max(yA,yB, yMax)
1775
if ABeta > 2*pi and ABeta <= beta+2*pi:
1776
xmin= min(xC-R,xmin)
1777
xMax= max(xC+R,xMax)
1778
ymin= min(yC-R, ymin)
1779
yMax= max(yC+R, yMax)
1780
if (xA<xC) and (yA<=yC):
1781
beta=atan(abs(yA-yC)/abs(xA-xC))
1782
j=4; ABeta=(alpha+beta)
1783
#say(str(degrees(beta))+" beta "+ str(degrees(ABeta))+" ABeta\r\n")
1786
if ABeta >= beta and ABeta <= pi/2:
1791
if ABeta > pi/2 and ABeta <= pi:
1794
ymin= min(yC-R,ymin)
1795
yMax= max(yA,yB,yMax)
1796
if ABeta > pi and ABeta <= 3/2*pi:
1798
xMax= max(xC+R,xMax)
1799
ymin= min(yC-R, ymin)
1801
if ABeta > 3/2*pi and ABeta <= 2*pi:
1802
xmin= min(xA,xB,xmin)
1803
xMax= max(xC+R,xMax)
1804
ymin= min(yC-R,ymin)
1805
yMax= max(yC+R, yMax)
1806
if ABeta > 2*pi and ABeta <= beta+2*pi:
1807
xmin= min(xC-R,xmin)
1808
xMax= max(xC+R,xMax)
1809
ymin= min(yC-R, ymin)
1810
yMax= max(yC+R, yMax)
1811
#say(str(j)+" case j\r\n")
1812
#say('xC='+str(xC)+';yC='+str(yC)+';xA='+str(xA)+';yA='+str(yA)+'\r\n')
1814
#calculating xmin of arc
1815
R=sqrt((xA-xC)**2+(yA-yC)**2)
1817
#say(str(xMax)+" xMax\r\n")
1818
#say(str(xmin)+" xmin\r\n")
1819
# print xMax, xmin, yMax, ymin
1821
#print (pcbarcs[n][8:].split(' ')[0])
1823
### end getArc_minMax
1825
def mid_point(prev_vertex,vertex,angle):
1826
"""mid_point(prev_vertex,vertex,angle)-> mid_vertex
1827
returns mid point on arc of angle between prev_vertex and vertex"""
1828
angle=radians(angle/2)
1829
basic_angle=atan2(vertex.y-prev_vertex.y,vertex.x-prev_vertex.x)-pi/2
1830
shift=(1-cos(angle))*hypot(vertex.y-prev_vertex.y,vertex.x-prev_vertex.x)/2/sin(angle)
1831
midpoint=Base.Vector((vertex.x+prev_vertex.x)/2+shift*cos(basic_angle),(vertex.y+prev_vertex.y)/2+shift*sin(basic_angle),0)
1835
def Per_point(prev_vertex,vertex):
1836
"""Per_point(center,vertex)->per point
1838
returns opposite perimeter point of circle"""
1839
#basic_angle=atan2(prev_vertex.y-vertex.y,prev_vertex.x-vertex.x)
1840
#shift=hypot(prev_vertex.y-vertex.y,prev_vertex.x-vertex.x)
1841
#perpoint=Base.Vector(prev_vertex.x+shift*cos(basic_angle),prev_vertex.y+shift*sin(basic_angle),0)
1842
perpoint=Base.Vector(2*prev_vertex.x-vertex.x,2*prev_vertex.y-vertex.y,0)
61
1846
#os.system("ps -C 'kicad-SteUp-tool' -o pid=|xargs kill -9")
63
1848
# UI Class definitions
1849
##if _platform == "linux" or _platform == "linux2":
1851
##elif _platform == "darwin":
1853
##elif _platform == "win32":
1856
#####################################
1857
# Function infoDialog
1858
#####################################
1859
def infoDialog(msg):
1860
#QtGui.qFreeCAD.setOverrideCursor(QtCore.Qt.WaitCursor)
1861
QtGui.qFreeCAD.restoreOverrideCursor()
1862
QtGui.qApp.restoreOverrideCursor()
1863
diag = QtGui.QMessageBox(QtGui.QMessageBox.Information,u"Info Message",msg )
1864
diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
1866
QtGui.qFreeCAD.restoreOverrideCursor()
1870
def getAuxAxisOrigin():
1871
match = re.search(r'\(aux_axis_origin (.+?) (.+?)\)', Kicad_Board)
1872
return [float(match.group(1)), float(match.group(2))];
1875
#####################################
1877
#####################################
65
1878
class RotateXYZGuiClass(QtGui.QWidget):
67
1880
def closeEvent(self, e):
68
1881
msg="""<b>Do you want to quit?</b>
69
1882
<font color='white'>****************************************************************************</font><br>
70
<i>Have you saved your STEP module</i><br>
71
<i>with the aligned Placement?</i>
1883
<i>Have you saved your STEP artwork?</i><br>
74
res = QtGui.QMessageBox.question(None,"Close",msg,QtGui.QMessageBox.Yes|QtGui.QMessageBox.No)
1886
QtGui.qApp.restoreOverrideCursor()
1887
self.setGeometry(25, 250, 500, 500)
1888
#self.setWindowState(QtCore.Qt.WindowMinimized)
1890
if test_flag_exit==False:
1891
QtGui.qApp.restoreOverrideCursor()
1892
res = QtGui.QMessageBox.question(None,"Close",msg,QtGui.QMessageBox.Yes|QtGui.QMessageBox.No)
75
1893
if res is QtGui.QMessageBox.No:
1895
#self.setWindowState(QtCore.Qt.WindowActive)
1896
doc=FreeCAD.ActiveDocument
1898
FreeCAD.setActiveDocument(doc.Name)
1899
#FreeCAD.ActiveDocument=FreeCAD.getDocument(doc.Label)
1900
#FreeCADGui.ActiveDocument=FreeCADGui.getDocument(doc.Label)
1902
FreeCAD.closeDocument(doc.Name)
78
1905
def link(self, linkStr):
79
1906
QtGui.QDesktopServices.openUrl(QtCore.QUrl(linkStr))
652
2607
self.label30.setText("X: "+str(event.x()) + " Y: "+str(event.y()))
654
2609
def onCreateAxis(self):
655
App.Console.PrintMessage("Create Axis!"+"\r\n")
656
if App.ActiveDocument.getObject("axis")== None:
2610
FreeCAD.Console.PrintMessage("Create Axis!"+"\r\n")
2611
if FreeCAD.ActiveDocument.getObject("axis")== None:
658
2613
## self.label10.setText("X:"+str(get_position()[0])+"Pl:"+str(get_position()[3]))
659
2614
## self.label11.setText("Y:"+str(get_position()[1])+"Pl:"+str(get_position()[4]))
660
2615
## self.label12.setText("Z:"+str(get_position()[2])+"Pl:"+str(get_position()[5]))
663
2617
# Class definitions
665
2619
# Function definitions
2620
def onLoadFootprint(file_name=None):
2621
#name=QtGui.QFileDialog.getOpenFileName(this,tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"))[0]
2622
#global module_3D_dir
2623
global last_fp_path, test_flag
2624
global configParser, configFilePath, start_time
2625
#self.setGeometry(25, 250, 500, 500)
2628
module_3D_dir=os.getenv('KISYS3DMOD', default_value)
2629
module_3D_dir=module_3D_dir+'/../'
2630
## getting 3D models path
2631
# print 'KISYS3DMOD='
2632
say('KISYS3DMOD='+os.getenv('KISYS3DMOD', default_value)+'\n'+module_3D_dir+'\n')
2633
if not os.path.isdir(module_3D_dir):
2635
if last_fp_path=='':
2636
last_fp_path=module_3D_dir
2638
#export_board_2step=True #for cmd line force exporting to STEP
2640
elif test_flag==False:
2641
#if test_flag==False:
2643
##if _platform == "darwin":
2644
## ##workaround for OSX not opening native fileopen
2645
## name=QtGui.QFileDialog.getOpenFileName(self, 'Open file',
2646
## last_file_path,"kicad module files (*.kicad_mod)",
2647
## options=QtGui.QFileDialog.DontUseNativeDialog )[0]
2649
## name=QtGui.QFileDialog.getOpenFileName(self, "Open File...", last_file_path,
2650
## "kicad module files (*.kicad_mod)")[0]
2651
#path = FreeCAD.ConfigGet("AppHomePath")
2652
#path = FreeCAD.ConfigGet("UserAppData")
2653
#path=last_file_path
2655
# name, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open File", last_file_path, "*.kicad_mod")#PySide
2657
# FreeCAD.Console.PrintError("Error : " + str(name) + "\n")
2658
name, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open File...",
2659
last_fp_path, "*.kicad_mod")
2661
name="C:/Cad/Progetti_K/ksu-test/test.kicad_mod"
2663
txtFile = __builtin__.open(name,"r")
2664
content = txtFile.readlines()
2666
last_fp_path=os.path.dirname(txtFile.name)
2668
configParser.set('last_footprint_path', 'last_fp_path', last_fp_path)
2669
#configParser.set('last_fp_path', ';; last footprint file path used')
2670
configParser.set('info', default_ksu_msg[0])
2671
configParser.set('prefix3D', default_ksu_msg[1])
2672
configParser.set('PcbColor', default_ksu_msg[2])
2673
configParser.set('Blacklist', default_ksu_msg[3])
2674
configParser.set('BoundingBox', default_ksu_msg[4])
2675
configParser.set('Placement', default_ksu_msg[5])
2676
configParser.set('Virtual', default_ksu_msg[6])
2677
configParser.set('ExportFuse', default_ksu_msg[7])
2678
configParser.set('minimum_drill_size', default_ksu_msg[8])
2679
configParser.set('last_pcb_path', default_ksu_msg[9])
2680
configParser.set('last_footprint_path', default_ksu_msg[10])
2681
configParser.set('export', default_ksu_msg[11])
2682
# save to the config file
2683
with __builtin__.open(configFilePath, 'wb') as configfile:
2684
configParser.write(configfile)
2685
#configFilePath.close() already closed
2686
data=''.join(content)
2687
content=re.sub(r'[^\x00-\x7F]+',' ', data)
2688
#FreeCAD.Console.PrintMessage(content)
2689
#FreeCAD.Console.PrintMessage(data)
2690
routineDrawFootPrint(content,name)
2693
def onLoadBoard_idf(file_name=None):
2694
#name=QtGui.QFileDialog.getOpenFileName(this,tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"))[0]
2695
#global module_3D_dir
2696
global models3D_prefix, blacklisted_model_elements, col, colr, colg, colb
2697
global bbox, volume_minimum, height_minimum, idf_to_origin, aux_orig
2698
global base_orig, base_point, bbox_all, bbox_list, whitelisted_model_elements
2699
global fusion, addVirtual, blacklisted_models, exportFusing, min_drill_size
2700
global last_fp_path, last_pcb_path, plcmnt, xp, yp, exportFusing
2701
global last_pcb_path, test_flag, configParser, configFilePath, start_time
2702
global aux_orig, base_orig, base_point, idf_to_origin, off_x, off_y, export_board_2step
2703
global real_board_pos_x, real_board_pos_y, board_base_point_x, board_base_point_y
2704
#self.setGeometry(25, 250, 500, 500)
2707
module_3D_dir=os.getenv('KISYS3DMOD', default_value)
2708
module_3D_dir=module_3D_dir+'/../'
2709
## getting 3D models path
2710
# print 'KISYS3DMOD='
2711
say('KISYS3DMOD='+os.getenv('KISYS3DMOD', default_value)+'\n'+module_3D_dir+'\n')
2712
if not os.path.isdir(module_3D_dir):
2714
if not os.path.isdir(last_pcb_path):
2717
#export_board_2step=True #for cmd line force exporting to STEP
2719
elif test_flag==False:
2721
##if _platform == "darwin":
2722
## ##workaround for OSX not opening native fileopen
2723
## name=QtGui.QFileDialog.getOpenFileName(self, 'Open file',
2724
## last_file_path,"kicad module files (*.kicad_mod)",
2725
## options=QtGui.QFileDialog.DontUseNativeDialog )[0]
2727
## name=QtGui.QFileDialog.getOpenFileName(self, "Open File...", last_file_path,
2728
## "kicad module files (*.kicad_mod)")[0]
2729
#path = FreeCAD.ConfigGet("AppHomePath")
2730
#path = FreeCAD.ConfigGet("UserAppData")
2731
#path=last_file_path
2733
# name, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open File", last_file_path, "*.kicad_mod")#PySide
2735
# FreeCAD.Console.PrintError("Error : " + str(name) + "\n")
2737
#minimize main window
2738
## self.setWindowState(QtCore.Qt.WindowMinimized)
2739
## infoDialog('ciao')
2740
## reply = QtGui.QInputDialog.getText(None, "Hello","Enter your thoughts for the day:")
2742
## # user clicked OK
2743
## replyText = reply[0]
2745
## # user clicked Cancel
2746
## replyText = reply[0] # which will be "" if they clicked Cancel
2747
## #restore main window
2748
## self.setWindowState(QtCore.Qt.WindowActive)
2749
name, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open IDF File...",
2750
last_pcb_path, "*.emn")
2752
name="C:/Cad/Progetti_K/ksu-test/test.emn"
2753
FreeCAD.Console.PrintMessage('opening '+name+'\n')
2755
if os.path.isfile(name):
2756
say('opening '+name+'\n')
2757
path, fname = os.path.split(name)
2758
fname=os.path.splitext(fname)[0]
2759
#fpth = os.path.dirname(os.path.abspath(__file__))
2760
fpth = os.path.dirname(os.path.abspath(name))
2761
#filePath = os.path.split(os.path.realpath(__file__))[0]
2762
say ('my file path '+fpth+'\n')
2765
last_pcb_path = fpth
2767
# update existing value
2768
#say(default_ksu_msg)
2769
configParser.set('last_pcb_path', 'last_pcb_path', path)
2770
#configParser.set('last_pcb_path', ';; last pcb board path')
2771
configParser.set('info', default_ksu_msg[0])
2772
configParser.set('prefix3D', default_ksu_msg[1])
2773
configParser.set('PcbColor', default_ksu_msg[2])
2774
configParser.set('Blacklist', default_ksu_msg[3])
2775
configParser.set('BoundingBox', default_ksu_msg[4])
2776
configParser.set('Placement', default_ksu_msg[5])
2777
configParser.set('Virtual', default_ksu_msg[6])
2778
configParser.set('ExportFuse', default_ksu_msg[7])
2779
configParser.set('minimum_drill_size', default_ksu_msg[8])
2780
configParser.set('last_pcb_path', default_ksu_msg[9])
2781
configParser.set('last_footprint_path', default_ksu_msg[10])
2782
configParser.set('export', default_ksu_msg[11])
2783
# save to the config file
2784
with __builtin__.open(configFilePath, 'wb') as configfile:
2785
configParser.write(configfile)
2786
#configFilePath.close() already closed
2787
doc=FreeCAD.newDocument(fname)
2788
#last_file_path=os.path.dirname(fname)
2789
start_time=current_milli_time()
2790
routineDrawIDF(doc,name)
2792
say(name+' missing\r')
2794
##Placing board at configured position
2796
# pos board xm+(xM-xm)/2
2797
# pos board -(ym+(yM-ym)/2)
2798
center_x, center_y, bb_x, bb_y = findPcbCenter("Pcb")
2800
xMax=center_x+bb_x/2
2801
xmin=center_x-bb_x/2
2802
yMax=center_y+bb_y/2
2803
ymin=center_y-bb_y/2
2804
off_x=0; off_y=0 #offset of the board & modules
2806
xp=getAuxAxisOrigin()[0]; yp=-getAuxAxisOrigin()[1] #offset of the board & modules
2807
##off_x=-xp+xmin+(xMax-xmin)/2; off_y=-yp-(ymin+(yMax-ymin)/2) #offset of the board & modules
2808
off_x=-xp+center_x;off_y=-yp+center_y
2810
##off_x=xmin+(xMax-xmin)/2; off_y=-(ymin+(yMax-ymin)/2) #offset of the board & modules
2811
off_x=center_x;off_y=center_y
2813
##off_x=-xp+xmin+(xMax-xmin)/2; off_y=-yp-(ymin+(yMax-ymin)/2) #offset of the board & modules
2814
#off_x=-xp+center_x;off_y=-yp+center_y
2815
off_x=-xp+center_x;off_y=-yp+center_y
2816
## test maui board_base_point_x=(xMax-xmin)/2-off_x
2817
## test maui board_base_point_y=-((yMax-ymin)/2)-off_y
2818
#real_board_pos_x=xmin+(xMax-xmin)/2
2819
#real_board_pos_y=-(ymin+(yMax-ymin)/2)
2821
real_board_pos_x=center_x
2822
real_board_pos_y=center_y
2823
# doc = FreeCAD.ActiveDocument
2824
if idf_to_origin == True:
2825
board_base_point_x=-off_x
2826
board_base_point_y=-off_y
2829
#board_base_point_x=xmin+(xMax-xmin)/2-off_x
2830
#board_base_point_y=-(ymin+(yMax-ymin)/2)-off_y
2831
board_base_point_x=center_x-off_x
2832
board_base_point_y=center_y-off_y
2833
# not to be used by .kicad_pcb
2835
if idf_to_origin==True:
2836
msg+="IDF board has to be exported to Xref=0; Yref=0\r\n\r\n"
2837
# msg+="IDF board has NOT to be exported to real placement\r\npcbnew version < 6091\r\n\r\n"
2839
msg+="IDF board has to be exported to real placement (Auto Adjust)\r\n\r\n"
2840
# msg+="IDF board has NOT to be exported to Xref=0; Yref=0\r\npcbnew version >=6091\r\n\r\n"
2841
if (show_messages==True):
2842
QtGui.qApp.restoreOverrideCursor()
2843
reply = QtGui.QMessageBox.information(None,"info", msg)
2844
FreeCAD.ActiveDocument.getObject("Pcb").Placement = FreeCAD.Placement(FreeCAD.Vector(board_base_point_x,board_base_point_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
2845
## FreeCAD.ActiveDocument.getObject("Pcb").Placement = FreeCAD.Placement(FreeCAD.Vector(-off_x,-off_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
2846
FreeCADGui.SendMsgToActiveView("ViewFit")
2847
#ImportGui.insert(u"./c0603.step","demo_5D_vrml_from_step")
2848
doc.addObject("App::DocumentObjectGroup", "Step_Models")
2850
name_kicad_pcb=name[:-3]+"kicad_pcb"
2851
pcbThickness,modules,board_elab=LoadKicadBoard(name_kicad_pcb)
2853
#say('Alive4 prob time\n')
2854
#end_milli_time = current_milli_time()
2855
#say(str(start_time)+'*'+str(end_milli_time)+'start-end\n')
2857
blacklisted_model_elements=Load_models(pcbThickness,modules)
2858
if export_board_2step:
2860
Export2MCAD(blacklisted_model_elements)
2863
Display_info(blacklisted_model_elements)
2867
def onLoadBoard(file_name=None):
2868
#name=QtGui.QFileDialog.getOpenFileName(this,tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"))[0]
2869
#global module_3D_dir
2870
global test_flag, last_pcb_path, configParser, configFilePath, start_time
2871
global aux_orig, base_orig, base_point, idf_to_origin, off_x, off_y, export_board_2step
2872
global real_board_pos_x, real_board_pos_y, board_base_point_x, board_base_point_y
2873
global models3D_prefix, blacklisted_model_elements, col, colr, colg, colb
2874
global bbox, volume_minimum, height_minimum, idf_to_origin, aux_orig
2875
global base_orig, base_point, bbox_all, bbox_list, whitelisted_model_elements
2876
global fusion, addVirtual, blacklisted_models, exportFusing, min_drill_size
2877
global last_fp_path, last_pcb_path, plcmnt, xp, yp, exportFusing
2880
#lastPcb_dir='C:/Cad/Progetti_K/ksu-test'
2881
#say(lastPcb_dir+' last Pcb dir\r\n')
2882
if not os.path.isdir(last_pcb_path):
2884
#say(last_pcb_path+'\n')
2886
#export_board_2step=True #for cmd line force exporting to STEP
2888
elif test_flag==False:
2890
#minimize main window
2891
#self.setWindowState(QtCore.Qt.WindowMinimized)
2893
#reply = QtGui.QInputDialog.getText(None, "Hello","Enter your thoughts for the day:")
2896
# replyText = reply[0]
2898
# # user clicked Cancel
2899
# replyText = reply[0] # which will be "" if they clicked Cancel
2900
#restore main window
2901
#self.setWindowState(QtCore.Qt.WindowActive)
2902
name, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Open kicad PCB File...",
2903
last_pcb_path, "*.kicad_pcb")
2905
name="C:/Cad/Progetti_K/ksu-test/test.kicad_pcb"
2907
if os.path.isfile(name):
2908
say('opening '+name+'\n')
2909
path, fname = os.path.split(name)
2910
fname=os.path.splitext(fname)[0]
2911
#fpth = os.path.dirname(os.path.abspath(__file__))
2912
fpth = os.path.dirname(os.path.abspath(name))
2913
#filePath = os.path.split(os.path.realpath(__file__))[0]
2914
say ('my file path '+fpth+'\n')
2917
last_pcb_path = fpth
2919
# update existing value
2920
#say(default_ksu_msg)
2921
configParser.set('last_pcb_path', 'last_pcb_path', path)
2922
#configParser.set('last_pcb_path', ';; last pcb board path')
2923
configParser.set('info', default_ksu_msg[0])
2924
configParser.set('prefix3D', default_ksu_msg[1])
2925
configParser.set('PcbColor', default_ksu_msg[2])
2926
configParser.set('Blacklist', default_ksu_msg[3])
2927
configParser.set('BoundingBox', default_ksu_msg[4])
2928
configParser.set('Placement', default_ksu_msg[5])
2929
configParser.set('Virtual', default_ksu_msg[6])
2930
configParser.set('ExportFuse', default_ksu_msg[7])
2931
configParser.set('minimum_drill_size', default_ksu_msg[8])
2932
configParser.set('last_pcb_path', default_ksu_msg[9])
2933
configParser.set('last_footprint_path', default_ksu_msg[10])
2934
configParser.set('export', default_ksu_msg[11])
2935
# save to the config file
2936
with __builtin__.open(configFilePath, 'wb') as configfile:
2937
configParser.write(configfile)
2938
#configFilePath.close() already closed
2939
doc=FreeCAD.newDocument(fname)
2941
start_time=current_milli_time()
2942
pcbThickness,modules,board_elab=LoadKicadBoard(name)
2943
routineDrawPCB(pcbThickness,board_elab)
2945
say(name+' missing\r')
2947
##Placing board at configured position
2949
# pos board xm+(xM-xm)/2
2950
# pos board -(ym+(yM-ym)/2)
2951
center_x, center_y, bb_x, bb_y = findPcbCenter("Pcb")
2953
xMax=center_x+bb_x/2
2954
xmin=center_x-bb_x/2
2955
yMax=center_y+bb_y/2
2956
ymin=center_y-bb_y/2
2957
off_x=0; off_y=0 #offset of the board & modules
2959
xp=getAuxAxisOrigin()[0]; yp=-getAuxAxisOrigin()[1] #offset of the board & modules
2960
##off_x=-xp+xmin+(xMax-xmin)/2; off_y=-yp-(ymin+(yMax-ymin)/2) #offset of the board & modules
2961
off_x=-xp+center_x;off_y=-yp+center_y
2963
##off_x=xmin+(xMax-xmin)/2; off_y=-(ymin+(yMax-ymin)/2) #offset of the board & modules
2964
off_x=center_x;off_y=center_y
2966
##off_x=-xp+xmin+(xMax-xmin)/2; off_y=-yp-(ymin+(yMax-ymin)/2) #offset of the board & modules
2967
#off_x=-xp+center_x;off_y=-yp+center_y
2968
off_x=-xp+center_x;off_y=-yp+center_y
2969
## test maui board_base_point_x=(xMax-xmin)/2-off_x
2970
## test maui board_base_point_y=-((yMax-ymin)/2)-off_y
2971
#real_board_pos_x=xmin+(xMax-xmin)/2
2972
#real_board_pos_y=-(ymin+(yMax-ymin)/2)
2974
real_board_pos_x=center_x
2975
real_board_pos_y=center_y
2976
# doc = FreeCAD.ActiveDocument
2977
if idf_to_origin == True:
2978
board_base_point_x=-off_x
2979
board_base_point_y=-off_y
2982
#board_base_point_x=xmin+(xMax-xmin)/2-off_x
2983
#board_base_point_y=-(ymin+(yMax-ymin)/2)-off_y
2984
board_base_point_x=center_x-off_x
2985
board_base_point_y=center_y-off_y
2986
FreeCAD.ActiveDocument.getObject("Pcb").Placement = FreeCAD.Placement(FreeCAD.Vector(board_base_point_x,board_base_point_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
2987
## FreeCAD.ActiveDocument.getObject("Pcb").Placement = FreeCAD.Placement(FreeCAD.Vector(-off_x,-off_y,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
2988
FreeCADGui.SendMsgToActiveView("ViewFit")
2989
#ImportGui.insert(u"./c0603.step","demo_5D_vrml_from_step")
2990
doc.addObject("App::DocumentObjectGroup", "Step_Models")
2992
Load_models(pcbThickness,modules)
2993
if export_board_2step:
2995
Export2MCAD(blacklisted_model_elements)
2998
Display_info(blacklisted_model_elements)
666
3003
def routineR_XYZ(axe,alpha):
668
print 'routine Rotate XYZ'
669
Gui.activateWorkbench("PartWorkbench")
670
#Gui.SendMsgToActiveView("ViewFit")
671
##Gui.activeDocument().activeView().viewTop()
3005
say('routine Rotate XYZ\n')
3006
FreeCADGui.activateWorkbench("PartWorkbench")
3007
#FreeCADGui.SendMsgToActiveView("ViewFit")
3008
##FreeCADGui.activeDocument().activeView().viewTop()
672
3009
doc = FreeCAD.ActiveDocument
673
App.Console.PrintMessage("hereXYZ !"+"\r\n")
3010
#FreeCAD.Console.PrintMessage("hereXYZ !"+"\r\n")
674
3011
selEx = FreeCADGui.Selection.getSelectionEx()
675
3012
objs = [selobj.Object for selobj in selEx]
676
3013
if len(objs) == 1:
1145
3508
object_b.ViewObject.Visibility=False
1148
FreeCAD.Console.PrintMessage(
1149
3512
'No intersection between {} and {}\n'.format(
1153
3516
except Exception, e:
1154
3517
FreeCAD.Console.PrintWarning(u"{0}\n".format(e))
1155
#FreeCAD.Console.PrintMessage("here_collision\r\n")
3518
#say("here_collision\r\n")
1156
3519
return collisions
1158
3521
### end Collisions
1160
3523
def create_axis():
1162
App.ActiveDocument.addObject("App::DocumentObjectGroup", "axis")
3525
FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", "axis")
1164
App.ActiveDocument.addObject("Part::Box","AxisBoxZ")
1165
App.ActiveDocument.ActiveObject.Label = "CubeZ"
1166
App.ActiveDocument.addObject("Part::Cone","AxisConeZ")
1167
App.ActiveDocument.ActiveObject.Label = "ConeZ"
1168
App.ActiveDocument.getObject("AxisBoxZ").Width = '0 mm'
1169
App.ActiveDocument.getObject("AxisBoxZ").Width = '0.1 mm'
1170
App.ActiveDocument.getObject("AxisBoxZ").Length = '0 mm'
1171
App.ActiveDocument.getObject("AxisBoxZ").Length = '0.2 mm'
1172
App.ActiveDocument.getObject("AxisConeZ").Radius1 = '0 mm'
1173
App.ActiveDocument.getObject("AxisConeZ").Radius1 = '0.4 mm'
1174
App.ActiveDocument.getObject("AxisConeZ").Radius2 = '0 mm'
1175
App.ActiveDocument.getObject("AxisConeZ").Radius2 = '0.1 mm'
1176
App.ActiveDocument.getObject("AxisConeZ").Placement = App.Placement(App.Vector(0,0,9),App.Rotation(App.Vector(0,0,1),0))
1177
App.ActiveDocument.getObject("AxisConeZ").Height = '5 mm'
1178
App.ActiveDocument.getObject("AxisBoxZ").Placement = App.Placement(App.Vector(-0.1,-0.05,0),App.Rotation(App.Vector(0,0,1),0))
1179
Gui.ActiveDocument.getObject("AxisConeZ").ShapeColor = (0.0000,0.0000,1.0000)
1180
Gui.ActiveDocument.getObject("AxisBoxZ").ShapeColor = (0.0000,0.0000,1.0000)
1181
App.activeDocument().addObject("Part::MultiFuse","FusionAxisZ")
1182
App.activeDocument().FusionAxisZ.Shapes = [App.activeDocument().AxisBoxZ,App.activeDocument().AxisConeZ,]
1183
Gui.activeDocument().AxisBoxZ.Visibility=False
1184
Gui.activeDocument().AxisConeZ.Visibility=False
1185
Gui.ActiveDocument.FusionAxisZ.ShapeColor=Gui.ActiveDocument.AxisBoxZ.ShapeColor
1186
Gui.ActiveDocument.FusionAxisZ.DisplayMode=Gui.ActiveDocument.AxisBoxZ.DisplayMode
1187
App.ActiveDocument.recompute()
1188
App.ActiveDocument.addObject('Part::Feature','FusionAxisZ1').Shape=App.ActiveDocument.FusionAxisZ.Shape
1189
App.ActiveDocument.ActiveObject.Label = "Z"
3527
FreeCAD.ActiveDocument.addObject("Part::Box","AxisBoxZ")
3528
FreeCAD.ActiveDocument.ActiveObject.Label = "CubeZ"
3529
FreeCAD.ActiveDocument.addObject("Part::Cone","AxisConeZ")
3530
FreeCAD.ActiveDocument.ActiveObject.Label = "ConeZ"
3531
FreeCAD.ActiveDocument.getObject("AxisBoxZ").Width = '0 mm'
3532
FreeCAD.ActiveDocument.getObject("AxisBoxZ").Width = '0.1 mm'
3533
FreeCAD.ActiveDocument.getObject("AxisBoxZ").Length = '0 mm'
3534
FreeCAD.ActiveDocument.getObject("AxisBoxZ").Length = '0.2 mm'
3535
FreeCAD.ActiveDocument.getObject("AxisConeZ").Radius1 = '0 mm'
3536
FreeCAD.ActiveDocument.getObject("AxisConeZ").Radius1 = '0.4 mm'
3537
FreeCAD.ActiveDocument.getObject("AxisConeZ").Radius2 = '0 mm'
3538
FreeCAD.ActiveDocument.getObject("AxisConeZ").Radius2 = '0.1 mm'
3539
FreeCAD.ActiveDocument.getObject("AxisConeZ").Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,9),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3540
FreeCAD.ActiveDocument.getObject("AxisConeZ").Height = '5 mm'
3541
FreeCAD.ActiveDocument.getObject("AxisBoxZ").Placement = FreeCAD.Placement(FreeCAD.Vector(-0.1,-0.05,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3542
FreeCADGui.ActiveDocument.getObject("AxisConeZ").ShapeColor = (0.0000,0.0000,1.0000)
3543
FreeCADGui.ActiveDocument.getObject("AxisBoxZ").ShapeColor = (0.0000,0.0000,1.0000)
3544
FreeCAD.activeDocument().addObject("Part::MultiFuse","FusionAxisZ")
3545
FreeCAD.activeDocument().FusionAxisZ.Shapes = [FreeCAD.activeDocument().AxisBoxZ,FreeCAD.activeDocument().AxisConeZ,]
3546
FreeCADGui.activeDocument().AxisBoxZ.Visibility=False
3547
FreeCADGui.activeDocument().AxisConeZ.Visibility=False
3548
FreeCADGui.ActiveDocument.FusionAxisZ.ShapeColor=FreeCADGui.ActiveDocument.AxisBoxZ.ShapeColor
3549
FreeCADGui.ActiveDocument.FusionAxisZ.DisplayMode=FreeCADGui.ActiveDocument.AxisBoxZ.DisplayMode
3550
FreeCAD.ActiveDocument.recompute()
3551
FreeCAD.ActiveDocument.addObject('Part::Feature','FusionAxisZ1').Shape=FreeCAD.ActiveDocument.FusionAxisZ.Shape
3552
FreeCAD.ActiveDocument.ActiveObject.Label = "Z"
1191
Gui.ActiveDocument.ActiveObject.ShapeColor=(0.0000,0.0000,1.0000)
1192
obj=App.ActiveDocument.ActiveObject
1193
App.ActiveDocument.getObject("axis").addObject(obj)
1194
App.ActiveDocument.recompute()
1195
App.ActiveDocument.removeObject("FusionAxisZ")
1196
App.ActiveDocument.removeObject("AxisBoxZ")
1197
App.ActiveDocument.removeObject("AxisConeZ")
1198
App.ActiveDocument.recompute()
3554
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=(0.0000,0.0000,1.0000)
3555
obj=FreeCAD.ActiveDocument.ActiveObject
3556
FreeCAD.ActiveDocument.getObject("axis").addObject(obj)
3557
FreeCAD.ActiveDocument.recompute()
3558
FreeCAD.ActiveDocument.removeObject("FusionAxisZ")
3559
FreeCAD.ActiveDocument.removeObject("AxisBoxZ")
3560
FreeCAD.ActiveDocument.removeObject("AxisConeZ")
3561
FreeCAD.ActiveDocument.recompute()
1201
App.ActiveDocument.addObject("Part::Box","AxisBoxY")
1202
App.ActiveDocument.ActiveObject.Label = "CubeY"
1203
App.ActiveDocument.addObject("Part::Cone","AxisConeY")
1204
App.ActiveDocument.ActiveObject.Label = "ConeY"
1205
App.ActiveDocument.getObject("AxisBoxY").Width = '0 mm'
1206
App.ActiveDocument.getObject("AxisBoxY").Width = '0.1 mm'
1207
App.ActiveDocument.getObject("AxisBoxY").Length = '0 mm'
1208
App.ActiveDocument.getObject("AxisBoxY").Length = '0.2 mm'
1209
App.ActiveDocument.getObject("AxisConeY").Radius1 = '0 mm'
1210
App.ActiveDocument.getObject("AxisConeY").Radius1 = '0.4 mm'
1211
App.ActiveDocument.getObject("AxisConeY").Radius2 = '0 mm'
1212
App.ActiveDocument.getObject("AxisConeY").Radius2 = '0.1 mm'
1213
App.ActiveDocument.getObject("AxisConeY").Placement = App.Placement(App.Vector(0,0,9),App.Rotation(App.Vector(0,0,1),0))
1214
App.ActiveDocument.getObject("AxisConeY").Height = '5 mm'
1215
App.ActiveDocument.getObject("AxisBoxY").Placement = App.Placement(App.Vector(-0.1,-0.05,0),App.Rotation(App.Vector(0,0,1),0))
1216
Gui.ActiveDocument.getObject("AxisConeY").ShapeColor = (0.0000,1.0000,0.0000)
1217
Gui.ActiveDocument.getObject("AxisBoxY").ShapeColor = (0.0000,1.0000,0.0000)
1218
App.activeDocument().addObject("Part::MultiFuse","FusionAxisY")
1219
App.activeDocument().FusionAxisY.Shapes = [App.activeDocument().AxisBoxY,App.activeDocument().AxisConeY,]
1220
Gui.activeDocument().AxisBoxY.Visibility=False
1221
Gui.activeDocument().AxisConeY.Visibility=False
1222
Gui.ActiveDocument.FusionAxisY.ShapeColor=Gui.ActiveDocument.AxisBoxY.ShapeColor
1223
Gui.ActiveDocument.FusionAxisY.DisplayMode=Gui.ActiveDocument.AxisBoxY.DisplayMode
1224
App.ActiveDocument.recompute()
1225
App.ActiveDocument.addObject('Part::Feature','FusionAxisY1').Shape=App.ActiveDocument.FusionAxisY.Shape
1226
App.ActiveDocument.ActiveObject.Label = "Y"
3564
FreeCAD.ActiveDocument.addObject("Part::Box","AxisBoxY")
3565
FreeCAD.ActiveDocument.ActiveObject.Label = "CubeY"
3566
FreeCAD.ActiveDocument.addObject("Part::Cone","AxisConeY")
3567
FreeCAD.ActiveDocument.ActiveObject.Label = "ConeY"
3568
FreeCAD.ActiveDocument.getObject("AxisBoxY").Width = '0 mm'
3569
FreeCAD.ActiveDocument.getObject("AxisBoxY").Width = '0.1 mm'
3570
FreeCAD.ActiveDocument.getObject("AxisBoxY").Length = '0 mm'
3571
FreeCAD.ActiveDocument.getObject("AxisBoxY").Length = '0.2 mm'
3572
FreeCAD.ActiveDocument.getObject("AxisConeY").Radius1 = '0 mm'
3573
FreeCAD.ActiveDocument.getObject("AxisConeY").Radius1 = '0.4 mm'
3574
FreeCAD.ActiveDocument.getObject("AxisConeY").Radius2 = '0 mm'
3575
FreeCAD.ActiveDocument.getObject("AxisConeY").Radius2 = '0.1 mm'
3576
FreeCAD.ActiveDocument.getObject("AxisConeY").Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,9),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3577
FreeCAD.ActiveDocument.getObject("AxisConeY").Height = '5 mm'
3578
FreeCAD.ActiveDocument.getObject("AxisBoxY").Placement = FreeCAD.Placement(FreeCAD.Vector(-0.1,-0.05,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3579
FreeCADGui.ActiveDocument.getObject("AxisConeY").ShapeColor = (0.0000,1.0000,0.0000)
3580
FreeCADGui.ActiveDocument.getObject("AxisBoxY").ShapeColor = (0.0000,1.0000,0.0000)
3581
FreeCAD.activeDocument().addObject("Part::MultiFuse","FusionAxisY")
3582
FreeCAD.activeDocument().FusionAxisY.Shapes = [FreeCAD.activeDocument().AxisBoxY,FreeCAD.activeDocument().AxisConeY,]
3583
FreeCADGui.activeDocument().AxisBoxY.Visibility=False
3584
FreeCADGui.activeDocument().AxisConeY.Visibility=False
3585
FreeCADGui.ActiveDocument.FusionAxisY.ShapeColor=FreeCADGui.ActiveDocument.AxisBoxY.ShapeColor
3586
FreeCADGui.ActiveDocument.FusionAxisY.DisplayMode=FreeCADGui.ActiveDocument.AxisBoxY.DisplayMode
3587
FreeCAD.ActiveDocument.recompute()
3588
FreeCAD.ActiveDocument.addObject('Part::Feature','FusionAxisY1').Shape=FreeCAD.ActiveDocument.FusionAxisY.Shape
3589
FreeCAD.ActiveDocument.ActiveObject.Label = "Y"
1228
Gui.ActiveDocument.ActiveObject.ShapeColor=(0.0000,1.0000,0.000)
1229
obj=App.ActiveDocument.ActiveObject
1230
App.ActiveDocument.getObject("axis").addObject(obj)
1231
App.ActiveDocument.recompute()
1232
App.ActiveDocument.removeObject("FusionAxisY")
1233
App.ActiveDocument.removeObject("AxisBoxY")
1234
App.ActiveDocument.removeObject("AxisConeY")
1235
App.ActiveDocument.recompute()
1236
App.ActiveDocument.ActiveObject.Placement = App.Placement(App.Vector(0,0,0.05),App.Rotation(App.Vector(1,0,0),-90))
3591
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=(0.0000,1.0000,0.000)
3592
obj=FreeCAD.ActiveDocument.ActiveObject
3593
FreeCAD.ActiveDocument.getObject("axis").addObject(obj)
3594
FreeCAD.ActiveDocument.recompute()
3595
FreeCAD.ActiveDocument.removeObject("FusionAxisY")
3596
FreeCAD.ActiveDocument.removeObject("AxisBoxY")
3597
FreeCAD.ActiveDocument.removeObject("AxisConeY")
3598
FreeCAD.ActiveDocument.recompute()
3599
FreeCAD.ActiveDocument.ActiveObject.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0.05),FreeCAD.Rotation(FreeCAD.Vector(1,0,0),-90))
1239
App.ActiveDocument.addObject("Part::Box","AxisBoxX")
1240
App.ActiveDocument.ActiveObject.Label = "CubeX"
1241
App.ActiveDocument.addObject("Part::Cone","AxisConeX")
1242
App.ActiveDocument.ActiveObject.Label = "ConeX"
1243
App.ActiveDocument.getObject("AxisBoxX").Width = '0 mm'
1244
App.ActiveDocument.getObject("AxisBoxX").Width = '0.2 mm'
1245
App.ActiveDocument.getObject("AxisBoxX").Length = '0 mm'
1246
App.ActiveDocument.getObject("AxisBoxX").Length = '0.1 mm'
1247
App.ActiveDocument.getObject("AxisConeX").Radius1 = '0 mm'
1248
App.ActiveDocument.getObject("AxisConeX").Radius1 = '0.4 mm'
1249
App.ActiveDocument.getObject("AxisConeX").Radius2 = '0 mm'
1250
App.ActiveDocument.getObject("AxisConeX").Radius2 = '0.1 mm'
1251
App.ActiveDocument.getObject("AxisConeX").Placement = App.Placement(App.Vector(0,0,9),App.Rotation(App.Vector(0,0,1),0))
1252
App.ActiveDocument.getObject("AxisConeX").Height = '5 mm'
1253
App.ActiveDocument.getObject("AxisBoxX").Placement = App.Placement(App.Vector(-0.1,-0.05,0),App.Rotation(App.Vector(0,0,1),0))
1254
Gui.ActiveDocument.getObject("AxisConeX").ShapeColor = (1.0000,0.0000,0.0000)
1255
Gui.ActiveDocument.getObject("AxisBoxX").ShapeColor = (1.0000,0.0000,0.0000)
1256
App.activeDocument().addObject("Part::MultiFuse","FusionAxisX")
1257
App.activeDocument().FusionAxisX.Shapes = [App.activeDocument().AxisBoxX,App.activeDocument().AxisConeX,]
1258
Gui.activeDocument().AxisBoxX.Visibility=False
1259
Gui.activeDocument().AxisConeX.Visibility=False
1260
Gui.ActiveDocument.FusionAxisX.ShapeColor=Gui.ActiveDocument.AxisBoxX.ShapeColor
1261
Gui.ActiveDocument.FusionAxisX.DisplayMode=Gui.ActiveDocument.AxisBoxX.DisplayMode
1262
App.ActiveDocument.recompute()
1263
App.ActiveDocument.addObject('Part::Feature','FusionAxisX1').Shape=App.ActiveDocument.FusionAxisX.Shape
1264
App.ActiveDocument.ActiveObject.Label="X"
1266
Gui.ActiveDocument.ActiveObject.ShapeColor=(1.0000,0.0000,0.0000)
1267
obj=App.ActiveDocument.ActiveObject
1268
App.ActiveDocument.getObject("axis").addObject(obj)
1269
App.ActiveDocument.recompute()
1270
App.ActiveDocument.removeObject("FusionAxisX")
1271
App.ActiveDocument.removeObject("AxisBoxX")
1272
App.ActiveDocument.removeObject("AxisConeX")
1273
App.ActiveDocument.getObject("FusionAxisX1").Placement = App.Placement(App.Vector(0,-0.05,0),App.Rotation(App.Vector(0,1,0),90))
1275
App.ActiveDocument.recompute()
3602
FreeCAD.ActiveDocument.addObject("Part::Box","AxisBoxX")
3603
FreeCAD.ActiveDocument.ActiveObject.Label = "CubeX"
3604
FreeCAD.ActiveDocument.addObject("Part::Cone","AxisConeX")
3605
FreeCAD.ActiveDocument.ActiveObject.Label = "ConeX"
3606
FreeCAD.ActiveDocument.getObject("AxisBoxX").Width = '0 mm'
3607
FreeCAD.ActiveDocument.getObject("AxisBoxX").Width = '0.2 mm'
3608
FreeCAD.ActiveDocument.getObject("AxisBoxX").Length = '0 mm'
3609
FreeCAD.ActiveDocument.getObject("AxisBoxX").Length = '0.1 mm'
3610
FreeCAD.ActiveDocument.getObject("AxisConeX").Radius1 = '0 mm'
3611
FreeCAD.ActiveDocument.getObject("AxisConeX").Radius1 = '0.4 mm'
3612
FreeCAD.ActiveDocument.getObject("AxisConeX").Radius2 = '0 mm'
3613
FreeCAD.ActiveDocument.getObject("AxisConeX").Radius2 = '0.1 mm'
3614
FreeCAD.ActiveDocument.getObject("AxisConeX").Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,9),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3615
FreeCAD.ActiveDocument.getObject("AxisConeX").Height = '5 mm'
3616
FreeCAD.ActiveDocument.getObject("AxisBoxX").Placement = FreeCAD.Placement(FreeCAD.Vector(-0.1,-0.05,0),FreeCAD.Rotation(FreeCAD.Vector(0,0,1),0))
3617
FreeCADGui.ActiveDocument.getObject("AxisConeX").ShapeColor = (1.0000,0.0000,0.0000)
3618
FreeCADGui.ActiveDocument.getObject("AxisBoxX").ShapeColor = (1.0000,0.0000,0.0000)
3619
FreeCAD.activeDocument().addObject("Part::MultiFuse","FusionAxisX")
3620
FreeCAD.activeDocument().FusionAxisX.Shapes = [FreeCAD.activeDocument().AxisBoxX,FreeCAD.activeDocument().AxisConeX,]
3621
FreeCADGui.activeDocument().AxisBoxX.Visibility=False
3622
FreeCADGui.activeDocument().AxisConeX.Visibility=False
3623
FreeCADGui.ActiveDocument.FusionAxisX.ShapeColor=FreeCADGui.ActiveDocument.AxisBoxX.ShapeColor
3624
FreeCADGui.ActiveDocument.FusionAxisX.DisplayMode=FreeCADGui.ActiveDocument.AxisBoxX.DisplayMode
3625
FreeCAD.ActiveDocument.recompute()
3626
FreeCAD.ActiveDocument.addObject('Part::Feature','FusionAxisX1').Shape=FreeCAD.ActiveDocument.FusionAxisX.Shape
3627
FreeCAD.ActiveDocument.ActiveObject.Label="X"
3629
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor=(1.0000,0.0000,0.0000)
3630
obj=FreeCAD.ActiveDocument.ActiveObject
3631
FreeCAD.ActiveDocument.getObject("axis").addObject(obj)
3632
FreeCAD.ActiveDocument.recompute()
3633
FreeCAD.ActiveDocument.removeObject("FusionAxisX")
3634
FreeCAD.ActiveDocument.removeObject("AxisBoxX")
3635
FreeCAD.ActiveDocument.removeObject("AxisConeX")
3636
FreeCAD.ActiveDocument.getObject("FusionAxisX1").Placement = FreeCAD.Placement(FreeCAD.Vector(0,-0.05,0),FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90))
3638
FreeCAD.ActiveDocument.recompute()
1277
3640
#############################
1278
def createSolidBBox(model3D):
1279
#Gui.Selection.removeSelection(App.activeDocument().ActiveObject)
3641
def createSolidBBox2(model3D):
3642
#FreeCADGui.Selection.removeSelection(FreeCAD.activeDocument().ActiveObject)
1281
3644
selEx = FreeCADGui.Selection.getSelectionEx()
1282
3645
objs = [selobj.Object for selobj in selEx]
1283
3646
if len(objs) == 1:
1284
3647
s = objs[0].Shape
1285
3648
name=objs[0].Label
1286
App.Console.PrintMessage(name+" name \r\n")
3649
#say(name+" name \r\n")
1289
3652
boundBox_ = s.BoundBox
2443
4855
Holes = Part.makeCompound(HoleList)
2444
4856
Holes = Part.makeSolid(Holes)
2445
4857
Part.show(Holes)
2446
#App.Console.PrintMessage(App.ActiveDocument.ActiveObject.Name)
2447
App.ActiveDocument.ActiveObject.Label="Holes"
2448
Holes_name=App.ActiveDocument.ActiveObject.Name
2449
#App.Console.PrintMessage(Holes_name)
4858
#say(FreeCAD.ActiveDocument.ActiveObject.Name)
4859
FreeCAD.ActiveDocument.ActiveObject.Label="Holes"
4860
Holes_name=FreeCAD.ActiveDocument.ActiveObject.Name
2450
4862
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (0.67,1.00,0.50)
2451
4863
FreeCADGui.ActiveDocument.ActiveObject.Transparency = 70
2452
4864
THPs = Part.makeCompound(THPList)
2453
4865
THPs = Part.makeSolid(THPs)
2454
4866
Part.show(THPs)
2455
#App.Console.PrintMessage(App.ActiveDocument.ActiveObject.Name)
2456
App.ActiveDocument.ActiveObject.Label="PTHs"
2457
THPs_name=App.ActiveDocument.ActiveObject.Name
2458
#App.Console.PrintMessage(Holes_name)
4867
#say(FreeCAD.ActiveDocument.ActiveObject.Name)
4868
FreeCAD.ActiveDocument.ActiveObject.Label="PTHs"
4869
THPs_name=FreeCAD.ActiveDocument.ActiveObject.Name
2459
4871
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (0.67,1.00,0.50)
2460
4872
FreeCADGui.ActiveDocument.ActiveObject.Transparency = 70
2462
4874
fp_group=FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", footprint_name+'fp')
2463
App.Console.PrintMessage(fp_group.Name)
4875
say(fp_group.Label+'\n')
2465
4877
if len(FrontSilk)>0:
2466
obj2 = App.ActiveDocument.getObject(FSilk_name)
4878
obj2 = FreeCAD.ActiveDocument.getObject(FSilk_name)
2467
4879
list.append(FSilk_name)
2468
4880
fp_group.addObject(obj2)
2471
4883
if len(TopPadList)>0:
2472
obj3 = App.ActiveDocument.getObject(TopPads_name)
4884
obj3 = FreeCAD.ActiveDocument.getObject(TopPads_name)
2473
4885
fp_group.addObject(obj3)
2474
4886
list.append(TopPads_name)
2475
4887
if len(BotPadList)>0:
2476
obj4 = App.ActiveDocument.getObject(BotPads_name)
4888
obj4 = FreeCAD.ActiveDocument.getObject(BotPads_name)
2477
4889
fp_group.addObject(obj4)
2478
4890
list.append(BotPads_name)
2480
4892
if len(HoleList)>0:
2481
obj5 = App.ActiveDocument.getObject(Holes_name)
4893
obj5 = FreeCAD.ActiveDocument.getObject(Holes_name)
2482
4894
fp_group.addObject(obj5)
2483
4895
list.append(Holes_name)
2484
obj6 = App.ActiveDocument.getObject(THPs_name)
4896
obj6 = FreeCAD.ActiveDocument.getObject(THPs_name)
2485
4897
fp_group.addObject(obj6)
2486
4898
list.append(THPs_name)
2489
4900
#objFp=Part.makeCompound(list)
2490
4901
#Part.show(objFp)
2491
#App.Console.PrintMessage(list)
2492
4903
doc=FreeCAD.ActiveDocument
2495
4906
for obj in fp_group.Group:
2496
# do what you want to automate
2497
4907
#if (obj.Label==fp_group.Label):
2498
#Gui.Selection.addSelection(obj)
4908
#FreeCADGui.Selection.addSelection(obj)
2499
4909
shape=obj.Shape.copy()
2500
#shape_name=App.ActiveDocument.ActiveObject.Name
4910
#shape_name=FreeCAD.ActiveDocument.ActiveObject.Name
2501
4911
list1.append(shape)
2502
4912
#Part.show(shape)
2503
4913
fp_objs.append(obj)
2504
#App.Console.PrintMessage("added")
2508
4917
#objFp=Part.makeCompound(shape)
2509
4918
objFp=Part.makeCompound(list1)
2510
4919
Part.show(objFp)
2512
obj = App.ActiveDocument.ActiveObject
2513
#App.Console.PrintMessage("h")
2514
Gui.Selection.addSelection(obj) # select the object
2516
#obj = App.ActiveDocument.getObject(objFp.Name)
2517
#Gui.Selection.addSelection(Gui.ActiveDocument.ActiveObject)
2518
#Gui.ActiveDocument.getObject(objFp.Name).BoundingBox = True
2520
createSolidBBox(obj)
2521
bbox=App.ActiveDocument.ActiveObject
2522
App.ActiveDocument.ActiveObject.Label ="Pcb_solid"
2523
pcb_solid_name=App.ActiveDocument.ActiveObject.Name
2524
App.ActiveDocument.removeObject(obj.Name)
2526
#Gui.ActiveDocument.getObject(bbox.Name).BoundingBox = True
4921
obj = FreeCAD.ActiveDocument.ActiveObject
4923
FreeCADGui.Selection.addSelection(obj) # select the object
4924
createSolidBBox2(obj)
4925
bbox=FreeCAD.ActiveDocument.ActiveObject
4926
FreeCAD.ActiveDocument.ActiveObject.Label ="Pcb_solid"
4927
pcb_solid_name=FreeCAD.ActiveDocument.ActiveObject.Name
4928
FreeCAD.ActiveDocument.removeObject(obj.Name)
4930
#FreeCADGui.ActiveDocument.getObject(bbox.Name).BoundingBox = True
2527
4931
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (0.664,0.664,0.496)
2528
4932
FreeCADGui.ActiveDocument.ActiveObject.Transparency = 80
2529
#obj6 = App.ActiveDocument.getObject(bbox.Name)
4933
#obj6 = FreeCAD.ActiveDocument.getObject(bbox.Name)
2530
4934
fp_group.addObject(bbox)
2533
4936
if len(HoleList)>0:
2534
#App.Console.PrintMessage("cutting base")
2535
#Gui.ActiveDocument.getObject(bbox.Name).BoundingBox = True
2536
#Gui.ActiveDocument.getObject(pcb_solid_name).BoundingBox = True
2537
#Gui.ActiveDocument.getObject(Holes_name).BoundingBox = True
2538
cut_base = App.ActiveDocument.getObject(pcb_solid_name).Shape
2539
#App.Console.PrintMessage("cutting")
2540
cutter = App.ActiveDocument.getObject(Holes_name).Shape
2541
#App.Console.PrintMessage("cutting2")
2542
cut_base=cut_base.cut(cutter)
2544
pcb_name=App.ActiveDocument.ActiveObject.Name
2545
App.ActiveDocument.ActiveObject.Label ="Pcb"
4937
cut_base = FreeCAD.ActiveDocument.getObject(pcb_solid_name).Shape
4938
for drill in HoleList:
4939
#Holes = Part.makeCompound(HoleList)
4940
hole = Part.makeSolid(drill)
4942
#hole_name=FreeCAD.ActiveDocument.ActiveObject.Name
4943
#cutter = FreeCAD.ActiveDocument.getObject(hole_name).Shape
4944
cut_base=cut_base.cut(hole)
4946
pcb_name=FreeCAD.ActiveDocument.ActiveObject.Name
4947
FreeCAD.ActiveDocument.ActiveObject.Label ="Pcb"
2546
4948
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (0.664,0.664,0.496)
2547
4949
FreeCADGui.ActiveDocument.ActiveObject.Transparency = 80
2548
#App.Console.PrintMessage("cutted")
2549
pcb=App.ActiveDocument.ActiveObject
4951
pcb=FreeCAD.ActiveDocument.ActiveObject
2550
4952
fp_group.addObject(pcb)
2551
#App.Console.PrintMessage("added")
2552
#App.activeDocument().recompute()
2553
App.ActiveDocument.removeObject(pcb_solid_name)
2554
App.ActiveDocument.removeObject(Holes_name)
4954
#FreeCAD.activeDocument().recompute()
4955
FreeCAD.ActiveDocument.removeObject(pcb_solid_name)
4956
FreeCAD.ActiveDocument.removeObject(Holes_name)
2558
4960
for obj in fp_group.Group:
2559
4961
# do what you want to automate
2560
4962
#if (obj.Label==fp_group.Label):
2561
#Gui.Selection.addSelection(obj)
4963
#FreeCADGui.Selection.addSelection(obj)
2562
4964
shape=obj.Shape.copy()
2563
#shape_name=App.ActiveDocument.ActiveObject.Name
4965
#shape_name=FreeCAD.ActiveDocument.ActiveObject.Name
2564
4966
list2.append(shape)
2565
4967
#Part.show(shape)
2566
4968
list2_objs.append(obj)
2567
#App.Console.PrintMessage("added")
2568
#App.Console.PrintMessage(list2)
2569
#App.Console.PrintMessage('here1')
2571
4973
#Draft.rotate(list2_objs,90.0,FreeCAD.Vector(0.0,0.0,0.0),axis=FreeCAD.Vector(-0.0,-0.0,1.0),copy=False)
2572
#App.Console.PrintMessage('here1')
2574
4976
rot=[0,0,rot_wrl]
2575
4977
rotateObjs(list2_objs, rot)
2577
4979
for obj in fp_group.Group:
2578
Gui.Selection.removeSelection(obj)
2579
#App.Console.PrintMessage('here2')
2581
Gui.SendMsgToActiveView("ViewFit")
2582
#pads_found=getPadsList(content)
4980
FreeCADGui.Selection.removeSelection(obj)
4983
FreeCADGui.SendMsgToActiveView("ViewFit")
4984
#pads_found=getPadsList(content)
4988
def routineDrawIDF(doc,filename):
4989
"""process_emn(document, filename)-> adds emn geometry from emn file"""
4991
msg='IDF_ImporterVersion='+IDF_ImporterVersion+'\n'
4993
emnfile=pythonopen(filename, "r")
4994
emn_unit=1.0 #presume milimeter like emn unit
4995
emn_version=2 #presume emn_version 2
4996
board_thickness=0 #presume 0 board height
4997
board_outline=[] #no outline
4998
drills=[] #no drills
4999
placement=[] #no placement
5000
place_item=[] #empty place item
5001
emnlines=emnfile.readlines()
5006
ignore_hole_size=min_drill_size
5008
for emnline in emnlines:
5009
emnrecords=split_records(emnline)
5010
if len( emnrecords )==0 : continue
5011
if len( emnrecords[0] )>4 and emnrecords[0][0:4]==".END":
5012
passed_sections.append(current_section)
5014
elif emnrecords[0][0]==".":
5015
current_section=emnrecords[0]
5018
if current_section==".HEADER" and section_counter==2:
5019
emn_version=int(float(emnrecords[1]))
5020
say("Emn version: "+emnrecords[1]+"\n")
5021
if current_section==".HEADER" and section_counter==3 and emnrecords[1]=="THOU":
5024
if current_section==".HEADER" and section_counter==3 and emnrecords[1]=="TNM":
5027
if current_section==".BOARD_OUTLINE" and section_counter==2:
5028
board_thickness=emn_unit*float(emnrecords[0])
5029
say("Found board thickness "+emnrecords[0]+"\n")
5030
if current_section==".BOARD_OUTLINE" and section_counter>2:
5031
board_outline.append([int(emnrecords[0]),float(emnrecords[1])*emn_unit,float(emnrecords[2])*emn_unit,float(emnrecords[3])])
5032
if current_section==".DRILLED_HOLES" and section_counter>1 and float(emnrecords[0])*emn_unit>ignore_hole_size:
5033
drills.append([float(emnrecords[0])*emn_unit,float(emnrecords[1])*emn_unit,float(emnrecords[2])*emn_unit])
5034
if current_section==".PLACEMENT" and section_counter>1 and fmod(section_counter,2)==0:
5036
place_item.append(emnrecords[2]) #Reference designator
5037
place_item.append(emnrecords[1]) #Component part number
5038
place_item.append(emnrecords[0]) #Package name
5039
if current_section==".PLACEMENT" and section_counter>1 and fmod(section_counter,2)==1:
5040
place_item.append(float(emnrecords[0])*emn_unit) #X
5041
place_item.append(float(emnrecords[1])*emn_unit) #Y
5043
place_item.append(float(emnrecords[2])*emn_unit) #Z maui
5044
#say("\nZ="+(str(float(emnrecords[2])))+"\n")
5045
place_item.append(float(emnrecords[emn_version])) #Rotation
5046
place_item.append(emnrecords[emn_version+1]) #Side
5047
place_item.append(emnrecords[emn_version+2]) #Place Status
5048
say(str(place_item)+"\n")
5049
placement.append(place_item)
5051
say("\n".join(passed_sections)+"\n")
5053
say("Proceed "+str(Process_board_outline(doc,board_outline,drills,board_thickness))+" outlines\n")
5054
## place_steps(doc,placement,board_thickness)
5057
def Process_board_outline(doc,board_outline,drills,board_thickness):
5058
"""Process_board_outline(doc,board_outline,drills,board_thickness)-> number proccesed loops
5059
adds emn geometry from emn file"""
5061
vertex_index=-1; #presume no vertex
5062
lines=-1 #presume no lines
5065
for point in board_outline:
5066
vertex=Base.Vector(point[1],point[2],0)
5070
elif lines==point[0]:
5071
if point[3]!=0 and point[3]!=360:
5072
out_shape.append(Part.Arc(prev_vertex,mid_point(prev_vertex,vertex,point[3]),vertex))
5073
#say("mid point "+str(mid_point)+"\n")
5075
per_point=Per_point(prev_vertex,vertex)
5076
out_shape.append(Part.Arc(per_point,mid_point(per_point,vertex,point[3]/2),vertex))
5077
out_shape.append(Part.Arc(per_point,mid_point(per_point,vertex,-point[3]/2),vertex))
5079
out_shape.append(Part.Line(prev_vertex,vertex))
5081
out_shape=Part.Shape(out_shape)
5082
out_shape=Part.Wire(out_shape.Edges)
5083
out_face.append(Part.Face(out_shape))
5089
out_shape=Part.Shape(out_shape)
5090
out_shape=Part.Wire(out_shape.Edges)
5091
out_face.append(Part.Face(out_shape))
5093
say("Added outline\n")
5095
say("Cutting shape inside outline\n")
5096
for otl_cut in out_face[1: ]:
5097
outline=outline.cut(otl_cut)
5098
#say("Cutting shape inside outline\n")
5100
say("Cutting holes inside outline\n")
5101
for drill in drills:
5102
#say("Cutting hole inside outline\n")
5103
out_shape=Part.makeCircle(drill[0]/2, Base.Vector(drill[1],drill[2],0))
5104
out_shape=Part.Wire(out_shape.Edges)
5105
outline=outline.cut(Part.Face(out_shape))
5106
doc_outline=doc.addObject("Part::Feature","Pcb")
5107
doc_outline.Shape=outline
5108
#FreeCADGui.Selection.addSelection(doc_outline)
5109
#FreeCADGui.runCommand("Draft_Upgrade")
5110
#outline=FreeCAD.ActiveDocument.getObject("Union").Shape
5111
#FreeCAD.ActiveDocument.removeObject("Union")
5112
#doc_outline=doc.addObject("Part::Feature","Board_outline")
5113
doc_outline.Shape=outline.extrude(Base.Vector(0,0,-board_thickness))
5114
grp=doc.addObject("App::DocumentObjectGroup", "Board_Geoms")
5115
grp.addObject(doc_outline)
5116
doc.Pcb.ViewObject.ShapeColor = (colr,colg,colb)
5118
#say(str(start_time));say('*'+str(end_milli_time)+'start-end')
5119
FreeCADGui.activeDocument().activeView().viewAxometric()
5120
FreeCADGui.SendMsgToActiveView("ViewFit")
5121
#doc.Pcb.ViewObject.ShapeColor=(0.0, 0.5, 0.0, 0.0)
5126
def split_records(line_record):
5127
"""split_records(line_record)-> list of strings(records)
5129
standard separator list separator is space, records containting encapsulated by " """
5131
quote_pos=line_record.find('"')
5132
while quote_pos!=-1:
5134
split_result.extend(line_record[ :quote_pos].split())
5135
line_record=line_record[quote_pos: ]
5136
quote_pos=line_record.find('"',1)
5138
quote_pos=line_record.find('"',1)
5140
split_result.append(line_record[ :quote_pos+1])
5141
line_record=line_record[quote_pos+1: ]
5143
split_result.append(line_record)
5145
quote_pos=line_record.find('"')
5146
split_result.extend(line_record.split())
5150
#def routineDrawPCB(content,pcbThickness,board_elab):
5151
def routineDrawPCB(pcbThickness,board_elab):
5153
#for item in content:
5155
# x1, y1, x2, y2, width
5156
say("PCB Loader \n")
5157
doc=FreeCAD.activeDocument()
5158
for obj in FreeCAD.ActiveDocument.Objects:
5159
FreeCADGui.Selection.removeSelection(obj)
5172
totalHeight=pcbThickness
5175
#for i in getArc('Edge.Cuts', content, 'gr_arc'):
5176
for i in getArc('Edge.Cuts', board_elab, 'gr_arc'):
5182
arc1=Part.Edge(Part.Arc(Base.Vector(x2,y2,0),mid_point(Base.Vector(x2,y2,0),Base.Vector(x1,y1,0),i[4]),Base.Vector(x1,y1,0)))
5183
#arc1=Part.Edge(getCurvedLine(x2, y2,x1, y1, i[4]))
5184
#say(arc1.Curve.EndPoint) #to do maui
5188
#FreeCAD.ActiveDocument.ActiveObject.supportedProperties()
5189
#say(FreeCAD.ActiveDocument.ActiveObject.Shape.Name)
5190
PCB.append(['Arc', i[0], i[1], i[2], i[3], i[4]])
5193
#for i in getCircle('Edge.Cuts', content, 'gr_circle'):
5194
for i in getCircle('Edge.Cuts', board_elab, 'gr_circle'):
5199
circle1=Part.Edge(Part.Circle(Base.Vector(xs, ys,0), Base.Vector(0, 0, 1), r))
5200
##circle1=Part.makeCircle(Base.Vector(xs, ys,0), Base.Vector(0, 0, 1), r)
5201
##circle1=circle1.Edge
5204
circle1=Part.Wire(circle1)
5205
circle1=Part.Face(circle1)
5208
#circle1.translate(Base.Vector(0,0,-totalHeight))
5209
PCBs.append(circle1)
5211
PCB.append(['Circle', i[0], i[1], i[2]])
5214
#getLine('F.SilkS', content, 'fp_line')
5215
#for i in getLine('Edge.Cuts', content, 'gr_line'):
5216
for i in getLine('Edge.Cuts', board_elab, 'gr_line'):
5222
line1=Part.makeLine((x1, y1,0), (x2,y2,0))
5223
edges.append(line1);
5226
PCB.append(['Line', i[0], i[1], i[2], i[3]])
5228
#sort edges to form a single closed 2D shape
5230
if (not len(edges)>0):
5231
say ("no PCBs found")
5234
newEdges.append(edges.pop(0))
5236
#print [newEdges[0].Vertexes[0].Point]
5237
#print [newEdges[0].Vertexes[-1].Point]
5238
#say(str(len(newEdges[0].Vertexes)))
5239
nextCoordinate = newEdges[0].Vertexes[0].Point
5240
firstCoordinate = newEdges[0].Vertexes[-1].Point
5241
#nextCoordinate = newEdges[0].Curve.EndPoint
5242
#firstCoordinate = newEdges[0].Curve.StartPoint
5243
while(len(edges)>0 and loopcounter < 2):
5244
loopcounter = loopcounter + 1
5245
#print "nextCoordinate: ", nextCoordinate
5246
#if len(newEdges[0].Vertexes) > 1: # not circle
5247
for j, edge in enumerate(edges):
5248
#print "compare to: ", edges[j].Curve.StartPoint, "/" , edges[j].Curve.EndPoint
5249
#if edges[j].Curve.StartPoint == nextCoordinate:
5250
if edges[j].Vertexes[-1].Point == nextCoordinate:
5251
nextCoordinate = edges[j].Vertexes[0].Point
5252
newEdges.append(edges.pop(j))
5255
elif edges[j].Vertexes[0].Point == nextCoordinate:
5256
nextCoordinate = edges[j].Vertexes[-1].Point
5257
newEdges.append(edges.pop(j))
5260
if nextCoordinate == firstCoordinate:
5261
say('2d closed path\n')
5263
#say('\ntrying wire & face\n')
5264
#newEdges_old=newEdges
5265
## newEdges = Part.Wire(newEdges)
5266
#say('trying face\n')
5267
## newEdges = Part.Face(newEdges)
5268
newEdges = OpenSCAD2Dgeom.edgestofaces(newEdges)
5270
#newEdges.translate(Base.Vector(0,0,-totalHeight))
5273
#newEdges = newEdges.extrude(Base.Vector(0,0,totalHeight))
5274
PCBs.append(newEdges)
5277
newEdges.append(edges.pop(0))
5278
nextCoordinate = newEdges[0].Vertexes[0].Point
5279
firstCoordinate = newEdges[0].Vertexes[-1].Point
5280
except Part.OCCError: # Exception: #
5281
say("error in creating PCB")
5284
if loopcounter == 2:
5285
say("*** omitting PCBs because there was a not closed loop in your edge lines ***\n")
5286
say("*** have a look at position x=" + str(nextCoordinate.x) + "mm, y=" + str(nextCoordinate.y) + "mm ***\n")
5287
say('pcb edge not closed\n')
5288
QtGui.qApp.restoreOverrideCursor()
5289
diag = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Critical,
5290
'Error in creating Board Edge ."+"\r\n"',
5291
'Try Loading IDF(.emn) instead of .kicad_pcb or \nreview your Board Edges in Kicad!\nposition x=' + str(nextCoordinate.x) + 'mm, y=' + str(nextCoordinate.y) + 'mm')
5292
diag.setWindowModality(QtCore.Qt.ApplicationModal)
5296
FreeCADGui.activeDocument().activeView().viewTop()
5297
FreeCADGui.SendMsgToActiveView("ViewFit")
5301
for extruded in PCBs:
5302
#search for orientation of each pcb in 3d space, save it (no transformation yet!)
5304
axis = Base.Vector(0,0,1)
5305
position = Base.Vector(0,0,0)
5308
#extrude_XLenght=FreeCAD.ActiveDocument.ActiveObject.Shape.BoundBox.XLength
5309
# extrude_XLenght=extruded.Length #perimeter
5310
extrude_XLenght=extruded.BoundBox.XLength
5311
#extrude_XLenght=FreeCAD.ActiveDocument.ActiveObject.Shape.Edges.Length
5312
if maxLenght < extrude_XLenght:
5313
maxLenght = extrude_XLenght
5315
#say('XLenght='+str(extrude_XLenght)+'\n')
5317
say('max Length='+str(maxLenght)+' index='+str(external_idx)+'\n')
5318
cut_base=PCBs[external_idx]
5320
for i in range (len(PCBs)):
5323
cut_base=cut_base.cut(cutter)
5325
cut_base = cut_base.extrude(Base.Vector(0,0,totalHeight))
5328
#cut_base_name=FreeCAD.ActiveDocument.ActiveObject.Name
5333
cut_base = cut_base.extrude(Base.Vector(0,0,totalHeight))
5337
FreeCAD.activeDocument().removeObject("Shape")
5338
###FreeCAD.ActiveDocument.recompute()
5341
say('pcb edge not found\n')
5342
QtGui.qApp.restoreOverrideCursor()
5343
diag = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Critical,
5344
'Error in creating Board Edge ."+"\r\n"',
5345
'Try Loading IDF(.emn) instead of .kicad_pcb or \nreview your Board Edges in Kicad!\n')
5346
diag.setWindowModality(QtCore.Qt.ApplicationModal)
5349
FreeCADGui.activeDocument().activeView().viewTop()
5350
FreeCADGui.SendMsgToActiveView("ViewFit")
5354
say("start cutting\n")
5356
HoleList = getPads(board_elab,pcbThickness)
5358
HoleList = getPads_flat(board_elab)
5359
#say('alive-getting holes\n')
5362
#cut_base = FreeCAD.ActiveDocument.getObject(cut_base_name).Shape
5363
#cut_base_name=FreeCAD.ActiveDocument.ActiveObject
5364
#cut_base_name=FreeCAD.ActiveDocument.ActiveObject.Name
5366
for drill in HoleList:
5367
#say("Cutting hole inside outline\n")
5370
drill = Part.makeSolid(drill)
5373
cut_base=cut_base.cut(drill)
5374
doc_outline=doc.addObject("Part::Feature","Pcb")
5375
doc_outline.Shape=cut_base
5376
doc_outline.Shape=cut_base.extrude(Base.Vector(0,0,-pcbThickness))
5377
#cut_base=cut_base.extrude(Base.Vector(0,0,-pcbThickness))
5378
#Part.show(cut_base)
5379
pcb_name=FreeCAD.ActiveDocument.ActiveObject.Name
5380
pcb_board=FreeCAD.ActiveDocument.ActiveObject
5381
#FreeCAD.ActiveDocument.ActiveObject.Label ="Pcb"
5382
FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (colr,colg,colb)
5383
#FreeCADGui.ActiveDocument.ActiveObject.Transparency = 20
5385
#if remove_pcbPad==True:
5386
# FreeCAD.activeDocument().removeObject(cut_base_name)
5387
#FreeCAD.activeDocument().removeObject(Holes_name)
5388
grp=doc.addObject("App::DocumentObjectGroup", "Board_Geoms")
5389
grp.addObject(pcb_board)
5390
#grp.addObject(doc_outline)
5393
FreeCADGui.activeDocument().activeView().viewAxometric()
5394
FreeCADGui.SendMsgToActiveView("ViewFit")
5395
#FreeCADGui.SendMsgToActiveView("ViewFit")
5396
#pads_found=getPadsList(content)
5405
# #filename="./psu-fc-1.wrl"
5406
#path, fname = os.path.split(args[2])
5407
#export_board_2step=True
5409
ext = os.path.splitext(os.path.basename(args[2]))[1]
5411
fname=os.path.splitext(os.path.basename(args[2]))[0]
5412
#say(filePath+' ');say(fname+' ');say(ext);say('\n')
5413
fullFileName=fullfname+".kicad_pcb"
5414
fileName=fname+".kicad_pcb"
5415
#filePath = os.path.dirname(os.path.abspath(__file__))
5416
filePath = os.path.dirname(os.path.abspath(fullFileName))
5417
#filePath = os.path.split(os.path.realpath(__file__))[0]
5418
say ('arg file path '+filePath+'\n')
5421
last_pcb_path = filePath
5422
#say(fullFileName+'\n')
5423
if os.path.exists(fullFileName):
5424
#say("opening "+ fullFileName+'\n')
5425
cfgParsWrite(configFilePath)
5426
onLoadBoard(fullFileName)
5428
fullfilePath=filePath+os.sep+fname+".kicad_pcb"
5429
#say(fullfilePath+'\n')
5430
if os.path.exists(fullfilePath):
5431
#say("opening "+ fullfilePath+'\n')
5432
cfgParsWrite(configFilePath)
5433
onLoadBoard(fullfilePath)
5435
sayw("missing "+ fullfilePath+'\n')
5436
sayw("missing "+ fullFileName+'\n')
5437
#say("error missing "+ fullfilePath+'\r\n')
5438
QtGui.qApp.restoreOverrideCursor()
5439
reply = QtGui.QMessageBox.information(None,"Error ...","... missing \r\n"+ fullfilePath+"\r\n... missing \r\n"+ fullFileName)
2587
5444
QtGui.QDesktopServices.openUrl(QtCore.QUrl("t"))
2589
# Constant definitions
2590
global userCancelled, userOK, show_mouse_pos, min_val, last_file_path, resetP
2593
global rot_wrl, test_flag
2599
#global module_3D_dir
2600
userCancelled = "Cancelled"
2602
show_mouse_pos = True
2603
#module_3D_dir="C:/Cad/Progetti_K/a_mod"
2604
___ver___ = "1.3.2.8"
2606
conflict_tolerance=1e-6 #volume tolerance
2609
5447
# code ***********************************************************************************
2611
5449
form = RotateXYZGuiClass()
2613
5452
#Word size: 64-bit
2614
5453
#Version: 0.15.4671 (Git)