Commit b6906965 authored by Andrey Filippov's avatar Andrey Filippov

added simple support for sub-assemblies, reordered assembly files to have small objects first

parent 4edcdbba
...@@ -59,6 +59,7 @@ ROOT_DIR = '~/parts/0393/export' ...@@ -59,6 +59,7 @@ ROOT_DIR = '~/parts/0393/export'
STEP_PARTS='~/parts/0393/export/step_parts' STEP_PARTS='~/parts/0393/export/step_parts'
#DIR_LIST = ["parts","subassy_flat"] #DIR_LIST = ["parts","subassy_flat"]
ASSEMBLY_PATH = "" ASSEMBLY_PATH = ""
ASSEMBLY_SUFFIX = "-ASSY"
INFO_DIR = "info" INFO_DIR = "info"
X3D_DIR = "x3d" X3D_DIR = "x3d"
X3D_EXT = ".x3d" X3D_EXT = ".x3d"
...@@ -1086,30 +1087,46 @@ def generateAssemblyX3d(assembly_path, ...@@ -1086,30 +1087,46 @@ def generateAssemblyX3d(assembly_path,
if assembly_path: if assembly_path:
assName,_ = os.path.splitext(os.path.basename(assembly_path)) assName,_ = os.path.splitext(os.path.basename(assembly_path))
else: else:
assName= FreeCAD.activeDocument().Objects[0].Label assName= FreeCAD.activeDocument().Objects[0].Label
x3dFile = os.path.join(ROOT_DIR,X3D_DIR,assName + X3D_EXT) # currently in the same directory as parts ass_with_suffix = assName
if not ass_with_suffix.endswith(ASSEMBLY_SUFFIX):
ass_with_suffix = assName + ASSEMBLY_SUFFIX
x3dFile = os.path.join(ROOT_DIR,X3D_DIR, ass_with_suffix + X3D_EXT) # currently in the same directory as parts
x3dNode = et.Element('x3d') x3dNode = et.Element('x3d')
x3dNode.set('profile', 'Interchange') x3dNode.set('profile', 'Interchange')
x3dNode.set('version', '3.3') x3dNode.set('version', '3.3')
sceneNode = et.SubElement(x3dNode, 'Scene') sceneNode = et.SubElement(x3dNode, 'Scene')
# Including file with (manually created) NavInfo, Cameras, etc that should not be overwritten when regenerating assembly model # Including file with (manually created) NavInfo, Cameras, etc that should not be overwritten when regenerating assembly model
inlineNode = et.SubElement(sceneNode, 'Inline') inlineNode = et.SubElement(sceneNode, 'Inline')
inlineNode.set('id', assName + '_config') inlineNode.set('id', ass_with_suffix + '_config')
inlineNode.set('url',assName + '_config'+ X3D_EXT) inlineNode.set('url',ass_with_suffix + '_config'+ X3D_EXT)
inlineNode.set('nameSpaceName',assName) inlineNode.set('nameSpaceName', ass_with_suffix )
modelNode = et.SubElement(sceneNode, 'Transform') modelNode = et.SubElement(sceneNode, 'Transform')
modelNode.set('id','transform_'+assName) modelNode.set('id','transform_'+ass_with_suffix)
modelNode.set('translation','%f %f %f'%(0,0,0)) modelNode.set('translation','%f %f %f'%(0,0,0))
modelNode.set('rotation','%f %f %f %f'%(0,0,0,0)) modelNode.set('rotation','%f %f %f %f'%(0,0,0,0))
defined_parts = {} # for each defined part holds index (for ID generation) defined_parts = {} # for each defined part holds index (for ID generation)
#TODO: Reorder parts - smallest (by a product og gyration radii) first
volumes=[]
for i, component in enumerate(components['objects']): for i, component in enumerate(components['objects']):
rg=component['principal']['RadiusOfGyration']
volumes.append((i,rg[0]*rg[1]*rg[2]))
volumes=sorted(volumes,key= lambda t: t[1])
# for i, component in enumerate(components['objects']):
for i, _ in volumes:
transformations = components['transformations'][i] # same structure as candidates, missing - {}'None' transformations = components['transformations'][i] # same structure as candidates, missing - {}'None'
if not transformations: if not transformations:
print("Component %d does not have any matches, ignoring. Candidates: %s"%(i,str(components['candidates'][i]))) print("Component %d does not have any matches, ignoring. Candidates: %s"%(i,str(components['candidates'][i])))
continue continue
part = transformations.keys()[0] part = transformations.keys()[0]
# rename part if there is the same one with ASSEMBLY_SUFFIX
part_name = part
if ASSEMBLY_SUFFIX and os.path.isfile( os.path.join(ROOT_DIR, X3D_DIR, part + ASSEMBLY_SUFFIX + X3D_EXT)) :
part_name = part + ASSEMBLY_SUFFIX
transformation = transformations[part] transformation = transformations[part]
bbox=components['solids'][i].BoundBox bbox=components['solids'][i].BoundBox
bboxCenter=((bbox.XMax + bbox.XMin)/2,(bbox.YMax + bbox.YMin)/2,(bbox.ZMax + bbox.ZMin)/2) bboxCenter=((bbox.XMax + bbox.XMin)/2,(bbox.YMax + bbox.YMin)/2,(bbox.ZMax + bbox.ZMin)/2)
...@@ -1123,30 +1140,30 @@ def generateAssemblyX3d(assembly_path, ...@@ -1123,30 +1140,30 @@ def generateAssemblyX3d(assembly_path,
else: else:
defined_parts[part] = 0 defined_parts[part] = 0
switchNode = et.SubElement(modelNode, 'Switch') switchNode = et.SubElement(modelNode, 'Switch')
switchNode.set('id','switch_'+part+":"+str(defined_parts[part])) switchNode.set('id','switch_'+part_name+":"+str(defined_parts[part]))
switchNode.set('class','switch_'+part) switchNode.set('class','switch_'+part_name)
switchNode.set('whichChoice','0') switchNode.set('whichChoice','0')
transformNode = et.SubElement(switchNode, 'Transform') transformNode = et.SubElement(switchNode, 'Transform')
transformNode.set('id','transform_'+part+":"+str(defined_parts[part])) transformNode.set('id','transform_'+part_name+":"+str(defined_parts[part]))
transformNode.set('class','transform_'+part) transformNode.set('class','transform_'+part_name)
transformNode.set('translation','%f %f %f'%transform['translation']) transformNode.set('translation','%f %f %f'%transform['translation'])
transformNode.set('rotation','%f %f %f %f'%transform['rotation']) transformNode.set('rotation','%f %f %f %f'%transform['rotation'])
groupNode = et.SubElement(transformNode, 'Group') groupNode = et.SubElement(transformNode, 'Group')
groupNode.set('id','group_'+part+":"+str(defined_parts[part])) groupNode.set('id','group_'+part_name+":"+str(defined_parts[part]))
groupNode.set('class','group_'+part) groupNode.set('class','group_'+part_name)
groupNode.set('bboxSize','%f %f %f'%bboxSize) groupNode.set('bboxSize','%f %f %f'%bboxSize)
groupNode.set('bboxCenter','%f %f %f'%bboxCenter) groupNode.set('bboxCenter','%f %f %f'%bboxCenter)
if defined_parts[part]: if defined_parts[part]:
groupNode.set('USE', part) groupNode.set('USE', part_name)
else: else:
groupNode.set('DEF', part) groupNode.set('DEF', part_name)
inlineNode = et.SubElement(groupNode, 'Inline') inlineNode = et.SubElement(groupNode, 'Inline')
inlineNode.set('id','inline_'+part+":"+str(defined_parts[part])) inlineNode.set('id','inline_'+part_name+":"+str(defined_parts[part]))
inlineNode.set('class','inline_'+part) inlineNode.set('class','inline_'+part_name)
# inlineNode.set('url',os.path.join(X3D_DIR,part + X3D_EXT)) # inlineNode.set('url',os.path.join(X3D_DIR,part_name + X3D_EXT))
inlineNode.set('url',part + X3D_EXT) inlineNode.set('url',part_name + X3D_EXT)
inlineNode.set('nameSpaceName',part) inlineNode.set('nameSpaceName',part_name)
oneliner= et.tostring(x3dNode) oneliner= et.tostring(x3dNode)
reparsed = minidom.parseString(oneliner) reparsed = minidom.parseString(oneliner)
...@@ -1212,7 +1229,7 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1212,7 +1229,7 @@ class X3dStepAssyDialog(QtGui.QWidget):
x3d_root_path = "" x3d_root_path = ""
step_parts_path = "" step_parts_path = ""
log_file = "" log_file = ""
assembly_suffix = ""
precision = 0.0001 precision = 0.0001
precision_area = 0.001 precision_area = 0.001
...@@ -1314,6 +1331,7 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1314,6 +1331,7 @@ class X3dStepAssyDialog(QtGui.QWidget):
config.set('paths', 'x3d_root_path', self.x3d_root_path) config.set('paths', 'x3d_root_path', self.x3d_root_path)
config.set('paths', 'step_parts_path', self.step_parts_path) config.set('paths', 'step_parts_path', self.step_parts_path)
config.set('paths', 'log_file', self.log_file) config.set('paths', 'log_file', self.log_file)
config.set('paths', 'assembly_suffix', self.assembly_suffix)
try: try:
config.add_section('precisions') config.add_section('precisions')
except: except:
...@@ -1344,6 +1362,10 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1344,6 +1362,10 @@ class X3dStepAssyDialog(QtGui.QWidget):
self.log_file = config.get('paths', 'log_file') self.log_file = config.get('paths', 'log_file')
except: except:
self.log_file = "" self.log_file = ""
try:
self.assembly_suffix = config.get('paths', 'assembly_suffix' )
except:
self.assembly_suffix = ASSEMBLY_SUFFIX
try: try:
self.precision= float(config.get('precisions', 'precision')) self.precision= float(config.get('precisions', 'precision'))
except: except:
...@@ -1387,6 +1409,12 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1387,6 +1409,12 @@ class X3dStepAssyDialog(QtGui.QWidget):
label_step_parts = QtGui.QLabel("Step parts directory") label_step_parts = QtGui.QLabel("Step parts directory")
self.step_parts_btn = QtGui.QPushButton(self.get_path_text(self.step_parts_path)) self.step_parts_btn = QtGui.QPushButton(self.get_path_text(self.step_parts_path))
self.step_parts_btn.setToolTip("Select directory containing all the parts STEP models. Will scan sub-directories") self.step_parts_btn.setToolTip("Select directory containing all the parts STEP models. Will scan sub-directories")
label_assembly_suffix = QtGui.QLabel("Assembly suffix")
self.lineedit_assembly_suffix = QtGui.QLineEdit()
self.lineedit_assembly_suffix.setText (self.assembly_suffix)
self.lineedit_assembly_suffix.setToolTip("Add this suffix to the assembly name when generating X3D, inline files with such suffix instead of the base ones")
self.help_btn = QtGui.QPushButton("?") self.help_btn = QtGui.QPushButton("?")
self.help_btn.setToolTip("Show description of this program") self.help_btn.setToolTip("Show description of this program")
self.execute_btn = QtGui.QPushButton("Convert") self.execute_btn = QtGui.QPushButton("Convert")
...@@ -1427,6 +1455,8 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1427,6 +1455,8 @@ class X3dStepAssyDialog(QtGui.QWidget):
self.x3d_root_btn.clicked.connect(self.selectX3dRoot) self.x3d_root_btn.clicked.connect(self.selectX3dRoot)
self.step_parts_btn.clicked.connect(self.selectStepParts) self.step_parts_btn.clicked.connect(self.selectStepParts)
self.lineedit_assembly_suffix.editingFinished.connect (self.editedAssemblySuffix)
self.lineedit_precision.editingFinished.connect (self.editedPrecision) self.lineedit_precision.editingFinished.connect (self.editedPrecision)
self.lineedit_precision_area.editingFinished.connect (self.editedPrecisionArea) self.lineedit_precision_area.editingFinished.connect (self.editedPrecisionArea)
self.lineedit_precision_volume.editingFinished.connect (self.editedPrecisionVolume) self.lineedit_precision_volume.editingFinished.connect (self.editedPrecisionVolume)
...@@ -1455,25 +1485,28 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1455,25 +1485,28 @@ class X3dStepAssyDialog(QtGui.QWidget):
layout.addWidget(label_log_file, 3, 0) layout.addWidget(label_log_file, 3, 0)
layout.addWidget(self.log_file_btn, 3, 1, 1, 3) layout.addWidget(self.log_file_btn, 3, 1, 1, 3)
layout.addWidget(label_precision, 4, 0) layout.addWidget(label_assembly_suffix, 4, 0)
layout.addWidget(self.lineedit_precision, 4, 1, 1, 1) layout.addWidget(self.lineedit_assembly_suffix, 4, 1, 1, 1)
layout.addWidget(label_precision, 5, 0)
layout.addWidget(self.lineedit_precision, 5, 1, 1, 1)
layout.addWidget(label_precision_area, 5, 0) layout.addWidget(label_precision_area, 6, 0)
layout.addWidget(self.lineedit_precision_area, 5, 1, 1, 1) layout.addWidget(self.lineedit_precision_area, 6, 1, 1, 1)
layout.addWidget(label_precision_volume, 6, 0) layout.addWidget(label_precision_volume, 7, 0)
layout.addWidget(self.lineedit_precision_volume, 6, 1, 1, 1) layout.addWidget(self.lineedit_precision_volume, 7, 1, 1, 1)
layout.addWidget(label_precision_gyration, 7, 0) layout.addWidget(label_precision_gyration, 8, 0)
layout.addWidget(self.lineedit_precision_gyration, 7, 1, 1, 1) layout.addWidget(self.lineedit_precision_gyration, 8, 1, 1, 1)
layout.addWidget(label_precision_inside, 8, 0) layout.addWidget(label_precision_inside, 9, 0)
layout.addWidget(self.lineedit_precision_inside, 8, 1, 1, 1) layout.addWidget(self.lineedit_precision_inside, 9, 1, 1, 1)
layout.addWidget(self.help_btn, 9, 0) layout.addWidget(self.help_btn, 10, 0)
layout.addWidget(self.offsets_btn, 9, 1) layout.addWidget(self.offsets_btn, 10, 1)
layout.addWidget(self.execute_btn, 9, 2) layout.addWidget(self.execute_btn, 10, 2)
layout.addWidget(self.bom_btn, 9, 3) layout.addWidget(self.bom_btn, 10, 3)
self.setLayout(layout) self.setLayout(layout)
...@@ -1516,6 +1549,10 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1516,6 +1549,10 @@ class X3dStepAssyDialog(QtGui.QWidget):
self.step_parts_btn.setText(self.get_path_text(self.step_parts_path)) self.step_parts_btn.setText(self.get_path_text(self.step_parts_path))
self.saveSettings() self.saveSettings()
def editedAssemblySuffix(self):
self.assembly_suffix = self.lineedit_assembly_suffix.text()
self.saveSettings()
def editedPrecision(self): def editedPrecision(self):
txt = self.lineedit_precision.text() txt = self.lineedit_precision.text()
try: try:
...@@ -1650,6 +1687,8 @@ class X3dStepAssyDialog(QtGui.QWidget): ...@@ -1650,6 +1687,8 @@ class X3dStepAssyDialog(QtGui.QWidget):
PRECISION_VOLUME = self.precision_volume PRECISION_VOLUME = self.precision_volume
PRECISION_GYRATION = self.precision_gyration PRECISION_GYRATION = self.precision_gyration
PRECISION_INSIDE = self.precision_inside PRECISION_INSIDE = self.precision_inside
ASSEMBLY_SUFFIX = self.assembly_suffix
self.saveSettings() self.saveSettings()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment