Macro Unfold Box: Difference between revisions
(icon) |
Galou breizh (talk | contribs) (Fix indentation in script) |
||
Line 49: | Line 49: | ||
<pre> |
<pre> |
||
'''FreeCAD Macro unfoldBox. |
|||
#*************************************************************************** |
|||
#* * |
|||
#* Copyright (c) 2013 - DoNovae/Herve BAILLY <hbl13@donovae.com> * |
|||
#* * |
|||
#* This program is free software; you can redistribute it and/or modify * |
|||
#* it under the terms of the GNU Lesser General Public License (LGPL) * |
|||
#* as published by the Free Software Foundation; either version 2 of * |
|||
#* the License, or (at your option) any later version. * |
|||
#* for detail see the LICENCE text file. * |
|||
#* * |
|||
#* This program is distributed in the hope that it will be useful, * |
|||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|||
#* GNU Library General Public License for more details. * |
|||
#* * |
|||
#* You should have received a copy of the GNU Library General Public * |
|||
#* License along with this program; if not, write to the Free Software * |
|||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * |
|||
#* USA * |
|||
#* * |
|||
#*************************************************************************** |
|||
Unroll of a ruled surface |
|||
''' |
|||
##################################### |
##################################### |
||
# SEE https://wiki.freecadweb.org/Macro_Unfold_Box. |
|||
# Macro unfoldBox |
|||
# *************************************************************************** |
|||
# Unroll of a ruled surface |
|||
# * * |
|||
##################################### |
|||
# * Copyright (c) 2013 - DoNovae/Herve BAILLY <hbl13@donovae.com> * |
|||
import FreeCAD , FreeCADGui , Part, Draft, math, Drawing , PySide, os |
|||
# * * |
|||
from PySide import QtGui,QtCore |
|||
# * This program is free software; you can redistribute it and/or modify * |
|||
# * it under the terms of the GNU Lesser General Public License (LGPL) * |
|||
# * as published by the Free Software Foundation; either version 2 of * |
|||
# * the License, or (at your option) any later version. * |
|||
# * for detail see the LICENCE text file. * |
|||
# * * |
|||
# * This program is distributed in the hope that it will be useful, * |
|||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|||
# * GNU Library General Public License for more details. * |
|||
# * * |
|||
# * You should have received a copy of the GNU Library General Public * |
|||
# * License along with this program; if not, write to the Free Software * |
|||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * |
|||
# * USA * |
|||
# * * |
|||
# *************************************************************************** |
|||
import os |
|||
import math |
|||
import FreeCAD, FreeCADGui, Draft |
|||
from PySide import QtGui, QtCore |
|||
from FreeCAD import Base |
from FreeCAD import Base |
||
fields_l = [] |
fields_l = [] |
||
unroll_l = [] |
unroll_l = [] |
||
##################################### |
##################################### |
||
# Functions |
|||
##################################### |
##################################### |
||
# Functions |
|||
##################################### |
|||
##################################### |
|||
##################################### |
|||
# Function errorDialog |
|||
##################################### |
|||
def errorDialog(msg): |
def errorDialog(msg): |
||
diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical,u |
diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical, u'Error Message',msg) |
||
diag.setWindowFlags( |
diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) |
||
diag.exec_() |
diag.exec_() |
||
##################################### |
|||
# Function proceed |
|||
##################################### |
|||
def proceed(): |
def proceed(): |
||
QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) |
QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('===========================================\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox: start.\n') |
||
try: |
try: |
||
file_name = fields_l[0].text() |
|||
scale = float(fields_l[1].text()) |
|||
scale_auto = scale_check.isChecked() |
scale_auto = scale_check.isChecked() |
||
a3 = a3_check.isChecked() |
a3 = a3_check.isChecked() |
||
cartridge = cartridge_check.isChecked() |
cartridge = cartridge_check.isChecked() |
||
onedrawing = onedrawing_check.isChecked() |
onedrawing = onedrawing_check.isChecked() |
||
sewed = sewed_check.isChecked() |
sewed = sewed_check.isChecked() |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.file_name: '+file_name+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.scale: '+str(scale)+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.scale_check: '+str(scale_auto)+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.a3_check: '+str(a3)+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.cartridge: '+str(cartridge)+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.onedrawing: '+str(onedrawing)+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox.sewed: '+str(sewed)+'\n') |
||
except: |
except: |
||
msg= |
msg = 'unfoldBox: wrong inputs...\n' |
||
FreeCAD.Console.PrintError(msg) |
FreeCAD.Console.PrintError(msg) |
||
errorDialog(msg) |
errorDialog(msg) |
||
QtGui.qApp.restoreOverrideCursor() |
QtGui.qApp.restoreOverrideCursor() |
||
DialogBox.hide() |
DialogBox.hide() |
||
# |
# |
||
# Get selection |
# Get selection |
||
# |
# |
||
sel=FreeCADGui.Selection.getSelection() |
sel = FreeCADGui.Selection.getSelection() |
||
objnames_l=[] |
|||
grp = FreeCAD.activeDocument().addObject('App::DocumentObjectGroup', str(file_name)) |
|||
objnames_l=[] |
|||
for objid in range(sel.__len__()): |
|||
tree_l=[] |
|||
obj = Draft.clone(sel[objid]) |
|||
grp=FreeCAD.activeDocument().addObject("App::DocumentObjectGroup", str(file_name)) |
|||
grp.addObject(obj) |
|||
objnames_l.append([ obj, sel[objid].Name ]) |
|||
grp.addObject(obj) |
|||
objnames_l.append( [ obj , sel[objid].Name ] ) |
|||
unfold=unfoldBox() |
unfold = unfoldBox() |
||
if sewed : |
if sewed : |
||
objnames_l=unfold.done(objnames_l) |
objnames_l = unfold.done(objnames_l) |
||
grp.addObject(objnames_l[0][0]) |
grp.addObject(objnames_l[0][0]) |
||
else: |
else: |
||
for objid in range( |
for objid in range(objnames_l.__len__()): |
||
unfold.moveXY(objnames_l[objid][0]) |
unfold.moveXY(objnames_l[objid][0]) |
||
id_ = 0 |
|||
while objnames_l.__len__() > 0: |
while objnames_l.__len__() > 0: |
||
draw=Drawing2d( |
draw = Drawing2d(scale, scale_auto, a3, cartridge, onedrawing, FreeCAD.activeDocument().Name, 'Page'+str(id_)) |
||
objnames_l=draw. |
objnames_l = draw.all_(objnames_l) |
||
id_ = id_+1 |
|||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox: obj_l= '+str(objnames_l.__len__())+'\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('unfoldBox: end.\n') |
||
FreeCAD.Console.PrintMessage( |
FreeCAD.Console.PrintMessage('===========================================\n') |
||
##################################### |
|||
# Function close |
|||
##################################### |
|||
def close(): |
def close(): |
||
DialogBox.hide() |
DialogBox.hide() |
||
##################################### |
|||
# Class unfoldBox |
|||
##################################### |
|||
class unfoldBox: |
class unfoldBox: |
||
def __init__(self): |
|||
##################################### |
|||
FreeCAD.Console.PrintMessage('unfoldBox.unfoldBox\n') |
|||
# Function __init__ |
|||
self.LIMIT = 0.0001 |
|||
##################################### |
|||
def __init__(self): |
|||
FreeCAD.Console.PrintMessage("unfoldBox.unfoldBox\n") |
|||
self.LIMIT=0.0001 |
|||
def done(self, objnames_l): |
|||
tree_l = self.makeTree(objnames_l) |
|||
for id_ in range(objnames_l.__len__()): |
|||
face = objnames_l[id_] |
|||
self.moveXY(face[0]) |
|||
self.sew(objnames_l, tree_l) |
|||
return self.fusion(objnames_l) |
|||
def makeTree(self, objnames_l): |
|||
##################################### |
|||
# Initialisation of tree_l. |
|||
# Function done |
|||
tree_l = [] |
|||
##################################### |
|||
for k in range(objnames_l.__len__()): |
|||
facek = objnames_l[k][0] |
|||
facek_l = [] |
|||
for i in range(facek.Shape.Edges.__len__()): |
|||
face=objnames_l[id] |
|||
if False and type(facek.Shape.Edges[i].Curve).__name__ != 'GeomLineSegment': |
|||
self.moveXY(face[0]) |
|||
facek_l.append([-1, -1]) |
|||
self.sew( objnames_l , tree_l ) |
|||
else: |
|||
# Search face link to the ith edge |
|||
vki0 = facek.Shape.Edges[i].Curve.StartPoint |
|||
vki1 = facek.Shape.Edges[i].Curve.EndPoint |
|||
found = False |
|||
for l in range(k+1, objnames_l.__len__()): |
|||
facel = objnames_l[l][0] |
|||
for j in range(facel.Shape.Edges.__len__()): |
|||
vlj0 = facel.Shape.Edges[j].Curve.StartPoint |
|||
vlj1 = facel.Shape.Edges[j].Curve.EndPoint |
|||
if vki0.__eq__(vlj0) and vki1.__eq__(vlj1): |
|||
arelinked = False |
|||
isfacek = False |
|||
isfacel = False |
|||
for kk in range(k-1): |
|||
for ii in range(tree_l[kk].__len__()): |
|||
if tree_l[kk][ii][0] == k: |
|||
isfacek = True |
|||
if tree_l[kk][ii][0] == l: |
|||
isfacel = True |
|||
if isfacek and isfacel: |
|||
arelinked = True |
|||
break |
|||
if not arelinked: |
|||
facek_l.append([l, j]) |
|||
found = True |
|||
break |
|||
if found: |
|||
break |
|||
if not found: |
|||
facek_l.append([-1, -1]) |
|||
tree_l.append(facek_l) |
|||
return tree_l |
|||
def sew(self, objnames_l, tree_l): |
|||
placed_l = [] |
|||
##################################### |
|||
for k in range(tree_l.__len__()): |
|||
# Function makeTree |
|||
iskplaced = False |
|||
##################################### |
|||
for p in range(placed_l.__len__()): |
|||
def makeTree(self,objnames_l): |
|||
if placed_l[p] == k: |
|||
# |
|||
iskplaced = True |
|||
# Initialisation of tree_l |
|||
if not iskplaced: |
|||
# |
|||
placed_l.append(k) |
|||
tree_l=[] |
|||
facek = tree_l[k] |
|||
for k in range( objnames_l.__len__() ): |
|||
objk = objnames_l[k][0] |
|||
for i in range(facek.__len__()): |
|||
facek_l=[] |
|||
edgeki = facek[i] |
|||
for i in range( facek.Shape.Edges.__len__() ): |
|||
l = edgeki[0] |
|||
if False and type(facek.Shape.Edges[i].Curve).__name__ != 'GeomLineSegment': |
|||
j = edgeki[1] |
|||
islplaced = False |
|||
else: |
|||
for p in range(placed_l.__len__()): |
|||
# |
|||
if placed_l[p] == l: |
|||
# Search face link to the ith edge |
|||
islplaced = True |
|||
# |
|||
break |
|||
vki0=facek.Shape.Edges[i].Curve.StartPoint |
|||
if not islplaced: |
|||
vki1=facek.Shape.Edges[i].Curve.EndPoint |
|||
placed_l.append(l) |
|||
found=False |
|||
if l >= 0 and not (islplaced and iskplaced): |
|||
for l in range( k+1 , objnames_l.__len__() ): |
|||
iskplaced = True |
|||
# Move facel.edgelj to facek.edgeki. |
|||
objl = objnames_l[l][0] |
|||
vki0 = objk.Shape.Edges[i].Curve.StartPoint |
|||
vki1 = objk.Shape.Edges[i].Curve.EndPoint |
|||
vlj0 = objl.Shape.Edges[j].Curve.StartPoint |
|||
vlj1 = objl.Shape.Edges[j].Curve.EndPoint |
|||
vk = vki1.sub(vki0) |
|||
vl = vlj1.sub(vlj0) |
|||
alpk = vk.getAngle(vl)*180/math.pi |
|||
alpl = vl.getAngle(vk)*180/math.pi |
|||
self.isPlanZ(objk) |
|||
if islplaced: |
|||
Draft.move(objk, vlj0.sub(vki0)) |
|||
else: |
|||
Draft.move(objl, vki0.sub(vlj0)) |
|||
if not arelinked: |
|||
self.isPlanZ(objk) |
|||
found=True |
|||
break |
|||
if found: break |
|||
if not found: facek_l.append([-1,-1]) |
|||
tree_l.append(facek_l) |
|||
return tree_l |
|||
if math.fabs(vk.dot(FreeCAD.Base.Vector(-vl.y, vl.x, 0))) > self.LIMIT: |
|||
if islplaced: |
|||
Draft.rotate(objk, -alpl, vlj0, self.vecto(vl, vk)) |
|||
else: |
|||
Draft.rotate(objl, -alpk, vki0, self.vecto(vk, vl)) |
|||
elif vk.dot(vl) < 0: |
|||
if islplaced: |
|||
Draft.rotate(objk, 180, vlj0, self.vecto(vl, FreeCAD.Base.Vector(-vl.y, vl.x, 0))) |
|||
else: |
|||
Draft.rotate(objl, 180, vki0, self.vecto(vk, FreeCAD.Base.Vector(-vk.y, vk.x, 0))) |
|||
# Verifications. |
|||
vki0 = objk.Shape.Edges[i].Curve.StartPoint |
|||
vki1 = objk.Shape.Edges[i].Curve.EndPoint |
|||
vlj0 = objl.Shape.Edges[j].Curve.StartPoint |
|||
vlj1 = objl.Shape.Edges[j].Curve.EndPoint |
|||
vk = vki1.sub(vki0) |
|||
vl = vlj1.sub(vlj0) |
|||
self.isPlanZ(objk) |
|||
# Flip or not. |
|||
##################################### |
|||
L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin) |
|||
# Function sew |
|||
W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin) |
|||
##################################### |
|||
S1 = L*W |
|||
def sew( self,objnames_l , tree_l ): |
|||
if islplaced: |
|||
placed_l=[] |
|||
Draft.rotate(objk, 180, vlj0, vl) |
|||
for k in range( tree_l.__len__() ): |
|||
else: |
|||
Draft.rotate(objl, 180, vki0, vk) |
|||
for p in range( placed_l.__len__() ): |
|||
L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin) |
|||
if placed_l[p] == k: |
|||
W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin) |
|||
iskplaced=True |
|||
S2 = L * W |
|||
if not iskplaced:placed_l.append(k) |
|||
if (S2 <= S1): |
|||
facek=tree_l[k] |
|||
if islplaced: |
|||
objk=objnames_l[k][0] |
|||
Draft.rotate(objk, 180, vlj0, vl) |
|||
for i in range( facek.__len__() ): |
|||
else: |
|||
Draft.rotate(objl, 180, vki0, vk) |
|||
l=edgeki[0] |
|||
self.isPlanZ(objk) |
|||
islplaced=False |
|||
for p in range( placed_l.__len__() ): |
|||
if placed_l[p] == l: |
|||
islplaced=True |
|||
break |
|||
if not islplaced: placed_l.append(l) |
|||
if l >= 0 and not ( islplaced and iskplaced ): |
|||
iskplaced=True |
|||
# |
|||
# Move facel.edgelj to facek.edgeki |
|||
# |
|||
objl=objnames_l[l][0] |
|||
vki0=objk.Shape.Edges[i].Curve.StartPoint |
|||
vki1=objk.Shape.Edges[i].Curve.EndPoint |
|||
vlj0=objl.Shape.Edges[j].Curve.StartPoint |
|||
vlj1=objl.Shape.Edges[j].Curve.EndPoint |
|||
vk=vki1.sub(vki0) |
|||
vl=vlj1.sub(vlj0) |
|||
alpk=vk.getAngle(vl)*180/math.pi |
|||
alpl=vl.getAngle(vk)*180/math.pi |
|||
self.isPlanZ(objk) |
|||
if islplaced: |
|||
Draft.move( objk , vlj0.sub(vki0) ) |
|||
else: |
|||
Draft.move( objl , vki0.sub(vlj0) ) |
|||
self.isPlanZ(objk) |
|||
def isPlanZ(self, obj): |
|||
if math.fabs( vk.dot(FreeCAD.Base.Vector(-vl.y,vl.x,0))) > self.LIMIT: |
|||
L = obj.Shape.BoundBox.XMax - obj.Shape.BoundBox.XMin |
|||
if islplaced: |
|||
W = obj.Shape.BoundBox.YMax - obj.Shape.BoundBox.YMin |
|||
Draft.rotate( objk , -alpl , vlj0 , self.vecto( vl , vk )) |
|||
H = obj.Shape.BoundBox.ZMax - obj.Shape.BoundBox.ZMin |
|||
else: |
|||
if H < self.LIMIT: |
|||
return True |
|||
elif vk.dot(vl)<0: |
|||
else: |
|||
return False |
|||
Draft.rotate( objk , 180 , vlj0 , self.vecto( vl , FreeCAD.Base.Vector(-vl.y,vl.x,0) )) |
|||
else: |
|||
Draft.rotate( objl , 180 , vki0 , self.vecto( vk , FreeCAD.Base.Vector(-vk.y,vk.x,0))) |
|||
# |
|||
# Verifications |
|||
# |
|||
vki0=objk.Shape.Edges[i].Curve.StartPoint |
|||
vki1=objk.Shape.Edges[i].Curve.EndPoint |
|||
vlj0=objl.Shape.Edges[j].Curve.StartPoint |
|||
vlj1=objl.Shape.Edges[j].Curve.EndPoint |
|||
vk=vki1.sub(vki0) |
|||
vl=vlj1.sub(vlj0) |
|||
self.isPlanZ(objk) |
|||
# |
|||
# Flip or not |
|||
# |
|||
L=max(objl.Shape.BoundBox.XMax,objk.Shape.BoundBox.XMax) - min( objl.Shape.BoundBox.XMin,objk.Shape.BoundBox.XMin) |
|||
W=max(objl.Shape.BoundBox.YMax,objk.Shape.BoundBox.YMax) - min( objl.Shape.BoundBox.YMin,objk.Shape.BoundBox.YMin) |
|||
S1=L*W |
|||
if islplaced: |
|||
dum=0 |
|||
Draft.rotate( objk , 180 , vlj0 ,vl) |
|||
else: |
|||
dum=0 |
|||
Draft.rotate( objl , 180 , vki0 ,vk) |
|||
L=max(objl.Shape.BoundBox.XMax,objk.Shape.BoundBox.XMax) - min( objl.Shape.BoundBox.XMin,objk.Shape.BoundBox.XMin) |
|||
W=max(objl.Shape.BoundBox.YMax,objk.Shape.BoundBox.YMax) - min( objl.Shape.BoundBox.YMin,objk.Shape.BoundBox.YMin) |
|||
S2=L*W |
|||
if (S2<=S1): |
|||
if islplaced: |
|||
dum=0 |
|||
Draft.rotate( objk , 180 , vlj0 ,vl) |
|||
else: |
|||
dum=0 |
|||
Draft.rotate( objl , 180 , vki0 ,vk) |
|||
self.isPlanZ(objk) |
|||
def fusion(self, objnames_l): |
|||
##################################### |
|||
# Init. |
|||
# Function isPlanZ |
|||
obj_l=[] |
|||
##################################### |
|||
objna_l=[] |
|||
def isPlanZ(self,obj): |
|||
obj0 = objnames_l[0][0];name=objnames_l[0][1] |
|||
L=obj.Shape.BoundBox.XMax - obj.Shape.BoundBox.XMin |
|||
objfuse = FreeCAD.activeDocument().addObject('Part::MultiFuse','Unfolding') |
|||
W=obj.Shape.BoundBox.YMax - obj.Shape.BoundBox.YMin |
|||
for k in range(objnames_l.__len__()): |
|||
H=obj.Shape.BoundBox.ZMax - obj.Shape.BoundBox.ZMin |
|||
objk = objnames_l[k][0] |
|||
obj_l.append(objk) |
|||
objfuse.Shapes = obj_l |
|||
else: |
|||
FreeCAD.activeDocument().recompute() |
|||
return False |
|||
objna_l.append([objfuse, name]) |
|||
return objna_l |
|||
def get2Vectors(self, shape): |
|||
v0 = FreeCAD.Base.Vector(0, 0, 0) |
|||
v1 = FreeCAD.Base.Vector(0, 0, 0) |
|||
edges= shape.Edges |
|||
##################################### |
|||
for id_ in range(edges.__len__()-1): |
|||
# Function fusion |
|||
va = edges[id_].Curve.EndPoint.sub(edges[id_].Curve.StartPoint) |
|||
##################################### |
|||
vb = edges[id_+1].Curve.EndPoint.sub(edges[id_+1].Curve.StartPoint) |
|||
def fusion(self,objnames_l): |
|||
if vb.sub(va).Length > v1.sub(v0).Length: |
|||
# |
|||
v0 = self.vect_copy(va);v1=self.vect_copy(vb) |
|||
# Init |
|||
return [v0, v1] |
|||
obj_l=[] |
|||
objna_l=[] |
|||
obj0=objnames_l[0][0];name=objnames_l[0][1] |
|||
objfuse=FreeCAD.activeDocument().addObject("Part::MultiFuse","Unfolding") |
|||
for k in range( objnames_l.__len__() ): |
|||
objk=objnames_l[k][0] |
|||
obj_l.append(objk) |
|||
objfuse.Shapes=obj_l |
|||
FreeCAD.activeDocument().recompute() |
|||
objna_l.append([objfuse,name]) |
|||
return objna_l |
|||
def vecto(self, vect1, vect2): |
|||
##################################### |
|||
'''Function vecto.''' |
|||
# Function get2Vectors |
|||
v= FreeCAD.Base.Vector(0, 0, 0) |
|||
##################################### |
|||
v.x = vect1.y*vect2.z-vect1.z*vect2.y |
|||
def get2Vectors(self,shape): |
|||
v.y = vect1.z*vect2.x-vect1.x*vect2.z |
|||
v0=FreeCAD.Base.Vector(0,0,0) |
|||
v.z = vect1.x*vect2.y-vect1.y*vect2.x |
|||
v1=FreeCAD.Base.Vector(0,0,0) |
|||
return v |
|||
def vect_copy(self, vect): |
|||
edges= shape.Edges |
|||
'''Return a copy of vector.''' |
|||
for id in range( edges.__len__()-1): |
|||
v = vect.add(FreeCAD.Base.Vector(0, 0, 0)) |
|||
va=edges[id].Curve.EndPoint.sub(edges[id].Curve.StartPoint) |
|||
return v |
|||
vb=edges[id+1].Curve.EndPoint.sub(edges[id+1].Curve.StartPoint) |
|||
if vb.sub(va).Length > v1.sub(v0).Length: |
|||
v0=self.vect_copy(va);v1=self.vect_copy(vb) |
|||
#FreeCAD.Console.PrintMessage("unfoldBox.get2Vectors: v0= {:s}, v1= {:s}\n".format(str(v0),str(v1))) |
|||
return [ v0 , v1 ] |
|||
def moveXY(self, obj): |
|||
##################################### |
|||
# Move to origin |
|||
# Function vecto |
|||
Draft.move(obj, FreeCAD.Base.Vector(-obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, -obj.Shape.BoundBox.ZMin)) |
|||
# - vect1,2: |
|||
# - return abs(sin) angle between |
|||
# 2 vectors |
|||
##################################### |
|||
def vecto( self,vect1, vect2 ): |
|||
v= FreeCAD.Base.Vector(0,0,0) |
|||
v.x=vect1.y*vect2.z-vect1.z*vect2.y |
|||
v.y=vect1.z*vect2.x-vect1.x*vect2.z |
|||
v.z=vect1.x*vect2.y-vect1.y*vect2.x |
|||
return v |
|||
# Find 2 vectors defining the plan of surface |
|||
tab = self.get2Vectors(obj.Shape) |
|||
v0 = tab[0] |
|||
v1 = tab[1] |
|||
norm = self.vecto(v0, v1) |
|||
norm.normalize() |
|||
# Rotate. |
|||
##################################### |
|||
if math.fabs(norm.x) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: |
|||
# Function vect_copy |
|||
Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(1, 0, 0)) |
|||
# - vect: |
|||
elif math.fabs(norm.y) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: |
|||
# - return copy of vector |
|||
Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(0, 1, 0)) |
|||
##################################### |
|||
else: |
|||
def vect_copy( self,vect): |
|||
# Rotate following the angle to the normal direction of the plan. |
|||
v= vect.add( FreeCAD.Base.Vector(0,0,0) ) |
|||
oz= FreeCAD.Base.Vector(0, 0, 1) |
|||
return v |
|||
alp = oz.getAngle(norm)*180/math.pi |
|||
Draft.rotate(obj, -alp, FreeCAD.Base.Vector(0, 0, 0), self.vecto(oz, norm)) |
|||
# Move to z = 0. |
|||
Draft.move(obj, FreeCAD.Base.Vector(0, 0, -obj.Shape.BoundBox.ZMin)) |
|||
##################################### |
|||
# Function movexy |
|||
##################################### |
|||
def moveXY( self,obj ): |
|||
# |
|||
# Move to origin |
|||
# |
|||
Draft.move( obj , FreeCAD.Base.Vector( -obj.Shape.BoundBox.XMin , -obj.Shape.BoundBox.YMin , -obj.Shape.BoundBox.ZMin )) |
|||
# |
|||
# Find 2 vectors defining the plan of surface |
|||
# |
|||
tab=self.get2Vectors( obj.Shape ) |
|||
v0=tab[0];v1=tab[1] |
|||
norm=self.vecto(v0,v1) |
|||
norm.normalize() |
|||
#FreeCAD.Console.PrintMessage("unfoldBox.moveXY: norm= {:s}\n".format(str(norm))) |
|||
# |
|||
# Rotate |
|||
# |
|||
if math.fabs(norm.x) < self.LIMIT and math.fabs(norm.y) < self.LIMIT: |
|||
dum=0 |
|||
elif math.fabs(norm.x) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: |
|||
Draft.rotate( obj , 90 , FreeCAD.Base.Vector(0,0,0) , FreeCAD.Base.Vector(1,0,0) ) |
|||
elif math.fabs(norm.y) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: |
|||
Draft.rotate( obj , 90 , FreeCAD.Base.Vector(0,0,0) , FreeCAD.Base.Vector(0,1,0) ) |
|||
else: |
|||
# |
|||
# Rotate following the angle to the normal direction of the plan |
|||
# |
|||
oz= FreeCAD.Base.Vector(0,0,1) |
|||
alp=oz.getAngle(norm)*180/math.pi |
|||
#FreeCAD.Console.PrintMessage("unfoldBox.moveXY: alp= "+str(alp)+"\n") |
|||
#FreeCAD.Console.PrintMessage("unfoldBox.moveXY: vecto= {:s}\n".format(str(self.vecto(oz,norm)))) |
|||
Draft.rotate( obj , -alp , FreeCAD.Base.Vector(0,0,0) , self.vecto( oz, norm )) |
|||
# |
|||
# Move to z=0 |
|||
# |
|||
Draft.move( obj , FreeCAD.Base.Vector( 0 , 0 , -obj.Shape.BoundBox.ZMin )) |
|||
L=obj.Shape.BoundBox.XMax - obj.Shape.BoundBox.XMin |
|||
W=obj.Shape.BoundBox.YMax - obj.Shape.BoundBox.YMin |
|||
H=obj.Shape.BoundBox.ZMax - obj.Shape.BoundBox.ZMin |
|||
##################################### |
|||
# Class Drawing2d |
|||
##################################### |
|||
class Drawing2d: |
class Drawing2d: |
||
def __init__(self, scale, scale_auto, a3, cartridge, onedrawing, drawing_name, page_name): |
|||
##################################### |
|||
"""Function __init__ |
|||
# - Scale |
|||
# - scale_auto |
|||
# - a3 |
|||
# - cartridge |
|||
# - onedrawing |
|||
##################################### |
|||
def __init__( self, scale , scale_auto , a3 , cartridge , onedrawing , drawing_name , page_name ): |
|||
self.TopX_H=0 |
|||
self.TopY_H=0 |
|||
self.TopX_V=0 |
|||
self.TopY_V=0 |
|||
self.TopX_Hmax=0 |
|||
self.TopY_Hmax=0 |
|||
self.TopX_Vmax=0 |
|||
self.TopY_Vmax=0 |
|||
self.a3=a3 |
|||
self.pts_nbr=100 |
|||
self.scale=scale |
|||
self.scale_auto=scale_auto |
|||
self.cartridge=cartridge |
|||
self.onedrawing=onedrawing |
|||
if self.a3: |
|||
self.L=420 |
|||
self.H=297 |
|||
self.marge=6 |
|||
else: |
|||
self.L=297 |
|||
self.H=210 |
|||
self.marge=6 |
|||
self.page_name=page_name |
|||
self.drawing_name=drawing_name |
|||
- scale |
|||
##################################### |
|||
- scale_auto |
|||
# Function newPage |
|||
- a3 |
|||
##################################### |
|||
- cartridge |
|||
def newPage( self ): |
|||
- onedrawing |
|||
freecad_dir=os.getenv('HOME')+"/.FreeCAD/Mod/unfoldBox" |
|||
""" |
|||
page = FreeCAD.activeDocument().addObject('Drawing::FeaturePage', self.page_name ) |
|||
self.TopX_H = 0 |
|||
self.TopY_H = 0 |
|||
self.TopX_V = 0 |
|||
page.Template = freecad_dir+'/A3_Landscape.svg' |
|||
self.TopY_V = 0 |
|||
self.TopX_Hmax = 0 |
|||
self.TopY_Hmax = 0 |
|||
self.TopX_Vmax = 0 |
|||
self.TopY_Vmax = 0 |
|||
self.a3 = a3 |
|||
self.pts_nbr = 100 |
|||
self.scale = scale |
|||
self.scale_auto = scale_auto |
|||
self.cartridge = cartridge |
|||
self.onedrawing = onedrawing |
|||
if self.a3: |
|||
self.L = 420 |
|||
self.H = 297 |
|||
self.marge = 6 |
|||
else: |
else: |
||
self.L = 297 |
|||
self.H = 210 |
|||
else: |
|||
self.marge = 6 |
|||
self.page_name = page_name |
|||
page.Template = freecad_dir+'/A4_Landscape.svg' |
|||
self.drawing_name = drawing_name |
|||
def newPage(self): |
|||
freecad_dir = os.getenv('HOME') + '/.FreeCAD/Mod/unfoldBox' |
|||
page = FreeCAD.activeDocument().addObject( |
|||
'Drawing::FeaturePage', self.page_name) |
|||
if self.a3: |
|||
if self.cartridge: |
|||
page.Template = freecad_dir+'/A3_Landscape.svg' |
|||
else: |
|||
page.Template = freecad_dir+'/A3_Landscape_Empty.svg' |
|||
else: |
else: |
||
if self.cartridge: |
|||
page.Template = freecad_dir+'/A4_Landscape_Empty.svg' |
|||
page.Template = freecad_dir+'/A4_Landscape.svg' |
|||
return page |
|||
else: |
|||
page.Template = freecad_dir+'/A4_Landscape_Empty.svg' |
|||
return page |
|||
def all_(self, objnames_l): |
|||
##################################### |
|||
obj_l = [] |
|||
# Function all |
|||
for objid in range(objnames_l.__len__()): |
|||
##################################### |
|||
if objid == 0 or not self.onedrawing: |
|||
def all( self, objnames_l ): |
|||
self.newPage() |
|||
obj_l=[] |
|||
obj_l.extend(self.done(objid, objnames_l[objid])) |
|||
for objid in range( objnames_l.__len__() ): |
|||
return obj_l |
|||
if objid == 0 or not self.onedrawing: |
|||
page = self.newPage() |
|||
obj_l.extend( self.done( objid , objnames_l[objid] )) |
|||
return obj_l |
|||
def done(self, id_, objname): |
|||
# Init. |
|||
obj_l = [] |
|||
obj = objname[0] |
|||
objname = objname[1] |
|||
xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin |
|||
ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin |
|||
if ymax > xmax: |
|||
Draft.rotate(obj, 90) |
|||
Draft.move(obj, |
|||
FreeCAD.Base.Vector( |
|||
-obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, 0)) |
|||
xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin |
|||
ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin |
|||
scale = min((self.L-4*self.marge) / xmax, (self.H-4*self.marge) / ymax) |
|||
if (not self.scale_auto) or (self.onedrawing): |
|||
scale = self.scale |
|||
if id_ == 0 or not self.onedrawing: |
|||
##################################### |
|||
# Init. |
|||
# Function done |
|||
FreeCAD.Console.PrintMessage('Dawing2d: init\n') |
|||
##################################### |
|||
self.TopX_H = self.marge*2 |
|||
def done( self, id , objname ): |
|||
self.TopY_H = self.marge*2 |
|||
# |
|||
TopX = self.TopX_H |
|||
# Init |
|||
TopY = self.TopY_H |
|||
# |
|||
self.TopX_H = self.TopX_H + xmax * scale + self.marge |
|||
obj_l=[] |
|||
self.TopY_H = self.TopY_H |
|||
obj=objname[0] |
|||
self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) |
|||
objname=objname[1] |
|||
self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge) |
|||
xmax=obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin |
|||
self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) |
|||
ymax=obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin |
|||
self.TopX_V = max(self.TopX_Vmax, self.TopX_V) |
|||
if ymax > xmax : |
|||
self.TopY_V = self.marge * 2 |
|||
elif self.onedrawing: |
|||
Draft.move( obj , FreeCAD.Base.Vector( -obj.Shape.BoundBox.XMin , -obj.Shape.BoundBox.YMin , 0)) |
|||
if self.TopX_H + xmax * scale < self.L: |
|||
xmax=obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin |
|||
if self.TopY_H + ymax * scale + self.marge*2 < self.H: |
|||
ymax=obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin |
|||
# H Add at right on same horizontal line. |
|||
FreeCAD.Console.PrintMessage('Dawing2d: horizontal\n') |
|||
TopX = self.TopX_H |
|||
TopY = self.TopY_H |
|||
self.TopX_H = self.TopX_H + xmax * scale + self.marge |
|||
self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) |
|||
self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge) |
|||
self.TopX_Vmax = max(self.TopX_Hmax, self.TopX_Vmax) |
|||
self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) |
|||
self.TopX_V = max(self.TopX_Vmax, self.TopX_V) |
|||
else: |
|||
# |
|||
# V Add at right on same horizontal line |
|||
# |
|||
FreeCAD.Console.PrintMessage('Dawing2d: vertival\n') |
|||
if self.TopX_V + ymax * scale + 2 * self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H: |
|||
Draft.rotate(obj, 90) |
|||
Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0)) |
|||
self.TopX_V = max(self.TopX_Vmax, self.TopX_V) |
|||
TopX = self.TopX_V |
|||
TopY = self.TopY_V |
|||
self.TopX_V = self.TopX_V + ymax * scale + self.marge |
|||
self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge) |
|||
else: |
|||
obj_l.append([obj, 'name']) |
|||
return obj_l |
|||
else: |
|||
# H Carriage return. |
|||
if (self.TopY_Hmax + ymax * scale + self.marge*2 < self.H): |
|||
FreeCAD.Console.PrintMessage('Dawing2d: carriage return: '+str(self.TopY_H + ymax * scale)+' > '+str(self.H)+'\n') |
|||
TopX = self.marge*2 |
|||
TopY = self.TopY_Hmax |
|||
self.TopX_H = TopX + xmax * scale + self.marge |
|||
self.TopY_H = TopY |
|||
self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) |
|||
self.TopY_Hmax = self.TopY_Hmax + ymax*scale+self.marge |
|||
self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) |
|||
self.TopX_V = max(self.TopX_Vmax, self.TopX_V) |
|||
else: |
|||
# V Add at right on same horizontal line. |
|||
FreeCAD.Console.PrintMessage('Dawing2d: vertical: ' + str(self.TopX_V) + ', ' + str(self.TopX_Vmax) + '\n') |
|||
if self.TopX_V + ymax * scale + 2*self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H : |
|||
Draft.rotate(obj, 90) |
|||
Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0)) |
|||
TopX = self.TopX_V |
|||
TopY = self.TopY_V |
|||
self.TopX_V = self.TopX_V + ymax * scale + self.marge |
|||
self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge) |
|||
else: |
|||
obj_l.append([obj, 'name']) |
|||
return obj_l |
|||
page = FreeCAD.activeDocument().getObject(self.page_name) |
|||
scale=min((self.L-4*self.marge)/xmax,(self.H-4*self.marge)/ymax) |
|||
Text = FreeCAD.activeDocument().addObject('Drawing::FeatureViewAnnotation', objname + '_txt') |
|||
if ( not self.scale_auto ) or ( self.onedrawing ) : |
|||
Text.Text = objname |
|||
Text.X = TopX + xmax / 2 * scale |
|||
Text.Y = TopY + ymax / 2 * scale |
|||
Text.Scale = 1 |
|||
TopView = FreeCAD.activeDocument().addObject('Drawing::FeatureViewPart', 'TopView') |
|||
TopView.Source = obj |
|||
TopView.Direction = (0.0, 0.0, 1) |
|||
TopView.Rotation = 0 |
|||
TopView.X = TopX |
|||
TopView.Y = TopY |
|||
TopView.ShowHiddenLines = True |
|||
TopView.Scale = scale |
|||
page.addObject(TopView) |
|||
page.addObject(Text) |
|||
FreeCAD.activeDocument().recompute() |
|||
return obj_l |
|||
if id == 0 or not self.onedrawing: |
|||
# |
|||
# Init |
|||
# |
|||
FreeCAD.Console.PrintMessage("Dawing2d: init\n") |
|||
self.TopX_H=self.marge*2 |
|||
self.TopY_H=self.marge*2 |
|||
TopX=self.TopX_H |
|||
TopY=self.TopY_H |
|||
self.TopX_H=self.TopX_H + xmax * scale + self.marge |
|||
self.TopY_H=self.TopY_H |
|||
self.TopX_Hmax=max( self.TopX_Hmax , self.TopX_H ) |
|||
self.TopY_Hmax=max( self.TopY_Hmax , self.TopY_H + ymax*scale+self.marge ) |
|||
self.TopX_Vmax=max( self.TopX_Vmax , self.TopX_Hmax ) |
|||
self.TopX_V=max(self.TopX_Vmax,self.TopX_V) |
|||
self.TopY_V=self.marge*2 |
|||
elif self.onedrawing: |
|||
if self.TopX_H + xmax * scale < self.L : |
|||
if self.TopY_H + ymax * scale + self.marge*2 < self.H : |
|||
# |
|||
# H Add at right on same horizontal line |
|||
# |
|||
FreeCAD.Console.PrintMessage("Dawing2d: horizontal\n") |
|||
TopX=self.TopX_H |
|||
TopY=self.TopY_H |
|||
self.TopX_H=self.TopX_H + xmax * scale + self.marge |
|||
self.TopX_Hmax=max( self.TopX_Hmax , self.TopX_H ) |
|||
self.TopY_Hmax=max( self.TopY_Hmax , self.TopY_H + ymax*scale+self.marge ) |
|||
self.TopX_Vmax=max( self.TopX_Hmax , self.TopX_Vmax ) |
|||
self.TopX_Vmax=max( self.TopX_Vmax , self.TopX_Hmax ) |
|||
self.TopX_V=max(self.TopX_Vmax,self.TopX_V) |
|||
else: |
|||
# |
|||
# V Add at right on same horizontal line |
|||
# |
|||
FreeCAD.Console.PrintMessage("Dawing2d: vertival\n") |
|||
if self.TopX_V + ymax * scale +2* self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H : |
|||
Draft.rotate( obj , 90 ) |
|||
Draft.move( obj , FreeCAD.Base.Vector( -obj.BoundBox.XMin , -obj.BoundBox.YMin , 0)) |
|||
self.TopX_V=max(self.TopX_Vmax, self.TopX_V) |
|||
TopX=self.TopX_V |
|||
TopY=self.TopY_V |
|||
self.TopX_V = self.TopX_V + ymax * scale + self.marge |
|||
self.TopY_Vmax=max( self.TopY_Vmax , self.TopY_V + xmax * scale + self.marge ) |
|||
else: |
|||
obj_l.append( [ obj , name ] ) |
|||
return obj_l |
|||
else: |
|||
# |
|||
# H Carriage return |
|||
# |
|||
if ( self.TopY_Hmax + ymax * scale + self.marge*2 < self.H ): |
|||
FreeCAD.Console.PrintMessage("Dawing2d: carriage return: "+str(self.TopY_H + ymax * scale )+" > "+str(self.H)+"\n") |
|||
TopX=self.marge*2 |
|||
TopY=self.TopY_Hmax |
|||
self.TopX_H=TopX + xmax * scale + self.marge |
|||
self.TopY_H=TopY |
|||
self.TopX_Hmax=max( self.TopX_Hmax , self.TopX_H ) |
|||
self.TopY_Hmax=self.TopY_Hmax + ymax*scale+self.marge |
|||
self.TopX_Vmax=max( self.TopX_Vmax , self.TopX_Hmax ) |
|||
self.TopX_V=max(self.TopX_Vmax,self.TopX_V) |
|||
else: |
|||
# |
|||
# V Add at right on same horizontal line |
|||
# |
|||
FreeCAD.Console.PrintMessage("Dawing2d: vertival: "+str(self.TopX_V)+" , "+str(self.TopX_Vmax)+"\n") |
|||
if self.TopX_V + ymax * scale + 2*self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H : |
|||
Draft.rotate( obj , 90 ) |
|||
Draft.move( obj , FreeCAD.Base.Vector( -obj.BoundBox.XMin , -obj.BoundBox.YMin , 0)) |
|||
TopX=self.TopX_V |
|||
TopY=self.TopY_V |
|||
self.TopX_V = self.TopX_V + ymax * scale + self.marge |
|||
self.TopY_Vmax=max( self.TopY_Vmax , self.TopY_V + xmax * scale + self.marge ) |
|||
else: |
|||
obj_l.append( [ obj , name ] ) |
|||
return obj_l |
|||
page=FreeCAD.activeDocument().getObject(self.page_name ) |
|||
Text=FreeCAD.activeDocument().addObject('Drawing::FeatureViewAnnotation', objname+"_txt") |
|||
Text.Text=objname |
|||
Text.X=TopX+xmax/2*scale |
|||
Text.Y=TopY+ymax/2*scale |
|||
Text.Scale=1 |
|||
TopView = FreeCAD.activeDocument().addObject('Drawing::FeatureViewPart','TopView') |
|||
TopView.Source = obj |
|||
TopView.Direction = (0.0,0.0,1) |
|||
TopView.Rotation = 0 |
|||
TopView.X = TopX |
|||
TopView.Y = TopY |
|||
TopView.ShowHiddenLines = True |
|||
TopView.Scale = scale |
|||
page.addObject(TopView) |
|||
page.addObject(Text) |
|||
FreeCAD.activeDocument().recompute() |
|||
return obj_l |
|||
##################################### |
|||
##################################### |
|||
# Dialog Box |
|||
##################################### |
##################################### |
||
# Dialog Box |
|||
##################################### |
##################################### |
||
fields = [[ |
fields = [['Group Name', 'Unfolding']] |
||
fields.append([ |
fields.append(['Scale', '1']) |
||
DialogBox = QtGui.QDialog() |
DialogBox = QtGui.QDialog() |
||
DialogBox.resize(250,250) |
DialogBox.resize(250, 250) |
||
DialogBox.setWindowTitle( |
DialogBox.setWindowTitle('unfoldBox') |
||
la = QtGui.QVBoxLayout(DialogBox) |
la = QtGui.QVBoxLayout(DialogBox) |
||
# Input fields. |
|||
# |
|||
for id_ in range(len(fields)): |
|||
la.addWidget(QtGui.QLabel(fields[id_][0])) |
|||
# |
|||
fields_l.append(QtGui.QLineEdit(fields[id_][1])) |
|||
la.addWidget( |
la.addWidget(fields_l[id_]) |
||
fields_l.append( QtGui.QLineEdit( fields[ id ][ 1 ] )) |
|||
la.addWidget( fields_l[ id ] ) |
|||
scale_check = QtGui.QCheckBox( |
scale_check = QtGui.QCheckBox(DialogBox) |
||
scale_check.setObjectName( |
scale_check.setObjectName('checkBox') |
||
scale_check.setChecked(True) |
scale_check.setChecked(True) |
||
la.addWidget(QtGui.QLabel( |
la.addWidget(QtGui.QLabel('Scale auto')) |
||
la.addWidget(scale_check) |
la.addWidget(scale_check) |
||
a3_check = QtGui.QCheckBox( |
a3_check = QtGui.QCheckBox(DialogBox) |
||
a3_check.setObjectName( |
a3_check.setObjectName('checkBox') |
||
la.addWidget(QtGui.QLabel( |
la.addWidget(QtGui.QLabel('A3 Format')) |
||
a3_check.setChecked(False) |
a3_check.setChecked(False) |
||
la.addWidget(a3_check) |
la.addWidget(a3_check) |
||
cartridge_check = QtGui.QCheckBox( |
cartridge_check = QtGui.QCheckBox(DialogBox) |
||
cartridge_check.setObjectName( |
cartridge_check.setObjectName('checkBox') |
||
la.addWidget(QtGui.QLabel( |
la.addWidget(QtGui.QLabel('Cartridge')) |
||
cartridge_check.setChecked(False) |
cartridge_check.setChecked(False) |
||
la.addWidget(cartridge_check) |
la.addWidget(cartridge_check) |
||
onedrawing_check = QtGui.QCheckBox( |
onedrawing_check = QtGui.QCheckBox(DialogBox) |
||
onedrawing_check.setObjectName( |
onedrawing_check.setObjectName('checkBox') |
||
la.addWidget(QtGui.QLabel( |
la.addWidget(QtGui.QLabel('Group drawings in page')) |
||
onedrawing_check.setChecked(True) |
onedrawing_check.setChecked(True) |
||
la.addWidget(onedrawing_check) |
la.addWidget(onedrawing_check) |
||
sewed_check = QtGui.QCheckBox( |
sewed_check = QtGui.QCheckBox(DialogBox) |
||
sewed_check.setObjectName( |
sewed_check.setObjectName('checkBox') |
||
la.addWidget(QtGui.QLabel( |
la.addWidget(QtGui.QLabel('Sewed surfaces')) |
||
sewed_check.setChecked(True) |
sewed_check.setChecked(True) |
||
la.addWidget(sewed_check) |
la.addWidget(sewed_check) |
||
Line 691: | Line 588: | ||
box = QtGui.QDialogButtonBox(DialogBox) |
box = QtGui.QDialogButtonBox(DialogBox) |
||
box.setOrientation(QtCore.Qt.Horizontal) |
box.setOrientation(QtCore.Qt.Horizontal) |
||
box.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) |
box.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) |
||
la.addWidget(box) |
la.addWidget(box) |
||
QtCore.QObject.connect(box, QtCore.SIGNAL( |
QtCore.QObject.connect(box, QtCore.SIGNAL('accepted()'), proceed) |
||
QtCore.QObject.connect(box, QtCore.SIGNAL( |
QtCore.QObject.connect(box, QtCore.SIGNAL('rejected()'), close) |
||
QtCore.QMetaObject.connectSlotsByName(DialogBox) |
QtCore.QMetaObject.connectSlotsByName(DialogBox) |
||
DialogBox.show() |
DialogBox.show() |
Revision as of 18:24, 10 March 2020
Description |
---|
The macro allows to unfold the surfaces of a box of any shape and to draw them on a page. This macro must be upgraded cause error indentation and space mixed with tabulation Macro version: 1.0 Last modified: 2013-09-20 Download: ToolBar Icon Author: Hervé B. |
Author |
Hervé B. |
Download |
ToolBar Icon |
Links |
Macros recipes How to install macros How to customize toolbars |
Macro Version |
1.0 |
Date last modified |
2013-09-20 |
FreeCAD Version(s) |
Default shortcut |
None |
See also |
None |
Description
The macro allows to unfold the surfaces of a box of any shape and to draw them on a page.
Macro_unfoldBox
Installation
Copy the code file of the macro in the directory :
- Linux & Mac : $home/.Freecad/Mod/unfoldBox.
- Windows : C:\Program Files\FreeCAD0.13
Add templates : A3_Landscape_Empty.svg A3_Landscape.svg A4_Landscape_Empty.svg A4_Landscape.svg
Cf Macro for unfolding box surfaces
Options
- Scale manual or automatic
- Page format: a3/a4, cartridge (cf FreeCAD templates)
- Group drawings in the same page as possible.
- Sew or not the edges of the pieces.
Instruction for use
- Select a box made with Part::Loft tool for example.
- Explode it (cf Draft menu) into plan pieces
- Select the surfaces
- Execute the macro
Script
Macro_unfoldBox.FCMacro
'''FreeCAD Macro unfoldBox. Unroll of a ruled surface ''' ##################################### # SEE https://wiki.freecadweb.org/Macro_Unfold_Box. # *************************************************************************** # * * # * Copyright (c) 2013 - DoNovae/Herve BAILLY <hbl13@donovae.com> * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * # * as published by the Free Software Foundation; either version 2 of * # * the License, or (at your option) any later version. * # * for detail see the LICENCE text file. * # * * # * This program is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU Library General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with this program; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** import os import math import FreeCAD, FreeCADGui, Draft from PySide import QtGui, QtCore from FreeCAD import Base fields_l = [] unroll_l = [] ##################################### # Functions ##################################### def errorDialog(msg): diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical, u'Error Message',msg) diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) diag.exec_() def proceed(): QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) FreeCAD.Console.PrintMessage('===========================================\n') FreeCAD.Console.PrintMessage('unfoldBox: start.\n') try: file_name = fields_l[0].text() scale = float(fields_l[1].text()) scale_auto = scale_check.isChecked() a3 = a3_check.isChecked() cartridge = cartridge_check.isChecked() onedrawing = onedrawing_check.isChecked() sewed = sewed_check.isChecked() FreeCAD.Console.PrintMessage('unfoldBox.file_name: '+file_name+'\n') FreeCAD.Console.PrintMessage('unfoldBox.scale: '+str(scale)+'\n') FreeCAD.Console.PrintMessage('unfoldBox.scale_check: '+str(scale_auto)+'\n') FreeCAD.Console.PrintMessage('unfoldBox.a3_check: '+str(a3)+'\n') FreeCAD.Console.PrintMessage('unfoldBox.cartridge: '+str(cartridge)+'\n') FreeCAD.Console.PrintMessage('unfoldBox.onedrawing: '+str(onedrawing)+'\n') FreeCAD.Console.PrintMessage('unfoldBox.sewed: '+str(sewed)+'\n') except: msg = 'unfoldBox: wrong inputs...\n' FreeCAD.Console.PrintError(msg) errorDialog(msg) QtGui.qApp.restoreOverrideCursor() DialogBox.hide() # # Get selection # sel = FreeCADGui.Selection.getSelection() objnames_l=[] grp = FreeCAD.activeDocument().addObject('App::DocumentObjectGroup', str(file_name)) for objid in range(sel.__len__()): obj = Draft.clone(sel[objid]) grp.addObject(obj) objnames_l.append([ obj, sel[objid].Name ]) unfold = unfoldBox() if sewed : objnames_l = unfold.done(objnames_l) grp.addObject(objnames_l[0][0]) else: for objid in range(objnames_l.__len__()): unfold.moveXY(objnames_l[objid][0]) id_ = 0 while objnames_l.__len__() > 0: draw = Drawing2d(scale, scale_auto, a3, cartridge, onedrawing, FreeCAD.activeDocument().Name, 'Page'+str(id_)) objnames_l = draw.all_(objnames_l) id_ = id_+1 FreeCAD.Console.PrintMessage('unfoldBox: obj_l= '+str(objnames_l.__len__())+'\n') FreeCAD.Console.PrintMessage('unfoldBox: end.\n') FreeCAD.Console.PrintMessage('===========================================\n') def close(): DialogBox.hide() class unfoldBox: def __init__(self): FreeCAD.Console.PrintMessage('unfoldBox.unfoldBox\n') self.LIMIT = 0.0001 def done(self, objnames_l): tree_l = self.makeTree(objnames_l) for id_ in range(objnames_l.__len__()): face = objnames_l[id_] self.moveXY(face[0]) self.sew(objnames_l, tree_l) return self.fusion(objnames_l) def makeTree(self, objnames_l): # Initialisation of tree_l. tree_l = [] for k in range(objnames_l.__len__()): facek = objnames_l[k][0] facek_l = [] for i in range(facek.Shape.Edges.__len__()): if False and type(facek.Shape.Edges[i].Curve).__name__ != 'GeomLineSegment': facek_l.append([-1, -1]) else: # Search face link to the ith edge vki0 = facek.Shape.Edges[i].Curve.StartPoint vki1 = facek.Shape.Edges[i].Curve.EndPoint found = False for l in range(k+1, objnames_l.__len__()): facel = objnames_l[l][0] for j in range(facel.Shape.Edges.__len__()): vlj0 = facel.Shape.Edges[j].Curve.StartPoint vlj1 = facel.Shape.Edges[j].Curve.EndPoint if vki0.__eq__(vlj0) and vki1.__eq__(vlj1): arelinked = False isfacek = False isfacel = False for kk in range(k-1): for ii in range(tree_l[kk].__len__()): if tree_l[kk][ii][0] == k: isfacek = True if tree_l[kk][ii][0] == l: isfacel = True if isfacek and isfacel: arelinked = True break if not arelinked: facek_l.append([l, j]) found = True break if found: break if not found: facek_l.append([-1, -1]) tree_l.append(facek_l) return tree_l def sew(self, objnames_l, tree_l): placed_l = [] for k in range(tree_l.__len__()): iskplaced = False for p in range(placed_l.__len__()): if placed_l[p] == k: iskplaced = True if not iskplaced: placed_l.append(k) facek = tree_l[k] objk = objnames_l[k][0] for i in range(facek.__len__()): edgeki = facek[i] l = edgeki[0] j = edgeki[1] islplaced = False for p in range(placed_l.__len__()): if placed_l[p] == l: islplaced = True break if not islplaced: placed_l.append(l) if l >= 0 and not (islplaced and iskplaced): iskplaced = True # Move facel.edgelj to facek.edgeki. objl = objnames_l[l][0] vki0 = objk.Shape.Edges[i].Curve.StartPoint vki1 = objk.Shape.Edges[i].Curve.EndPoint vlj0 = objl.Shape.Edges[j].Curve.StartPoint vlj1 = objl.Shape.Edges[j].Curve.EndPoint vk = vki1.sub(vki0) vl = vlj1.sub(vlj0) alpk = vk.getAngle(vl)*180/math.pi alpl = vl.getAngle(vk)*180/math.pi self.isPlanZ(objk) if islplaced: Draft.move(objk, vlj0.sub(vki0)) else: Draft.move(objl, vki0.sub(vlj0)) self.isPlanZ(objk) if math.fabs(vk.dot(FreeCAD.Base.Vector(-vl.y, vl.x, 0))) > self.LIMIT: if islplaced: Draft.rotate(objk, -alpl, vlj0, self.vecto(vl, vk)) else: Draft.rotate(objl, -alpk, vki0, self.vecto(vk, vl)) elif vk.dot(vl) < 0: if islplaced: Draft.rotate(objk, 180, vlj0, self.vecto(vl, FreeCAD.Base.Vector(-vl.y, vl.x, 0))) else: Draft.rotate(objl, 180, vki0, self.vecto(vk, FreeCAD.Base.Vector(-vk.y, vk.x, 0))) # Verifications. vki0 = objk.Shape.Edges[i].Curve.StartPoint vki1 = objk.Shape.Edges[i].Curve.EndPoint vlj0 = objl.Shape.Edges[j].Curve.StartPoint vlj1 = objl.Shape.Edges[j].Curve.EndPoint vk = vki1.sub(vki0) vl = vlj1.sub(vlj0) self.isPlanZ(objk) # Flip or not. L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin) W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin) S1 = L*W if islplaced: Draft.rotate(objk, 180, vlj0, vl) else: Draft.rotate(objl, 180, vki0, vk) L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin) W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin) S2 = L * W if (S2 <= S1): if islplaced: Draft.rotate(objk, 180, vlj0, vl) else: Draft.rotate(objl, 180, vki0, vk) self.isPlanZ(objk) def isPlanZ(self, obj): L = obj.Shape.BoundBox.XMax - obj.Shape.BoundBox.XMin W = obj.Shape.BoundBox.YMax - obj.Shape.BoundBox.YMin H = obj.Shape.BoundBox.ZMax - obj.Shape.BoundBox.ZMin if H < self.LIMIT: return True else: return False def fusion(self, objnames_l): # Init. obj_l=[] objna_l=[] obj0 = objnames_l[0][0];name=objnames_l[0][1] objfuse = FreeCAD.activeDocument().addObject('Part::MultiFuse','Unfolding') for k in range(objnames_l.__len__()): objk = objnames_l[k][0] obj_l.append(objk) objfuse.Shapes = obj_l FreeCAD.activeDocument().recompute() objna_l.append([objfuse, name]) return objna_l def get2Vectors(self, shape): v0 = FreeCAD.Base.Vector(0, 0, 0) v1 = FreeCAD.Base.Vector(0, 0, 0) edges= shape.Edges for id_ in range(edges.__len__()-1): va = edges[id_].Curve.EndPoint.sub(edges[id_].Curve.StartPoint) vb = edges[id_+1].Curve.EndPoint.sub(edges[id_+1].Curve.StartPoint) if vb.sub(va).Length > v1.sub(v0).Length: v0 = self.vect_copy(va);v1=self.vect_copy(vb) return [v0, v1] def vecto(self, vect1, vect2): '''Function vecto.''' v= FreeCAD.Base.Vector(0, 0, 0) v.x = vect1.y*vect2.z-vect1.z*vect2.y v.y = vect1.z*vect2.x-vect1.x*vect2.z v.z = vect1.x*vect2.y-vect1.y*vect2.x return v def vect_copy(self, vect): '''Return a copy of vector.''' v = vect.add(FreeCAD.Base.Vector(0, 0, 0)) return v def moveXY(self, obj): # Move to origin Draft.move(obj, FreeCAD.Base.Vector(-obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, -obj.Shape.BoundBox.ZMin)) # Find 2 vectors defining the plan of surface tab = self.get2Vectors(obj.Shape) v0 = tab[0] v1 = tab[1] norm = self.vecto(v0, v1) norm.normalize() # Rotate. if math.fabs(norm.x) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(1, 0, 0)) elif math.fabs(norm.y) < self.LIMIT and math.fabs(norm.z) < self.LIMIT: Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(0, 1, 0)) else: # Rotate following the angle to the normal direction of the plan. oz= FreeCAD.Base.Vector(0, 0, 1) alp = oz.getAngle(norm)*180/math.pi Draft.rotate(obj, -alp, FreeCAD.Base.Vector(0, 0, 0), self.vecto(oz, norm)) # Move to z = 0. Draft.move(obj, FreeCAD.Base.Vector(0, 0, -obj.Shape.BoundBox.ZMin)) class Drawing2d: def __init__(self, scale, scale_auto, a3, cartridge, onedrawing, drawing_name, page_name): """Function __init__ - scale - scale_auto - a3 - cartridge - onedrawing """ self.TopX_H = 0 self.TopY_H = 0 self.TopX_V = 0 self.TopY_V = 0 self.TopX_Hmax = 0 self.TopY_Hmax = 0 self.TopX_Vmax = 0 self.TopY_Vmax = 0 self.a3 = a3 self.pts_nbr = 100 self.scale = scale self.scale_auto = scale_auto self.cartridge = cartridge self.onedrawing = onedrawing if self.a3: self.L = 420 self.H = 297 self.marge = 6 else: self.L = 297 self.H = 210 self.marge = 6 self.page_name = page_name self.drawing_name = drawing_name def newPage(self): freecad_dir = os.getenv('HOME') + '/.FreeCAD/Mod/unfoldBox' page = FreeCAD.activeDocument().addObject( 'Drawing::FeaturePage', self.page_name) if self.a3: if self.cartridge: page.Template = freecad_dir+'/A3_Landscape.svg' else: page.Template = freecad_dir+'/A3_Landscape_Empty.svg' else: if self.cartridge: page.Template = freecad_dir+'/A4_Landscape.svg' else: page.Template = freecad_dir+'/A4_Landscape_Empty.svg' return page def all_(self, objnames_l): obj_l = [] for objid in range(objnames_l.__len__()): if objid == 0 or not self.onedrawing: self.newPage() obj_l.extend(self.done(objid, objnames_l[objid])) return obj_l def done(self, id_, objname): # Init. obj_l = [] obj = objname[0] objname = objname[1] xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin if ymax > xmax: Draft.rotate(obj, 90) Draft.move(obj, FreeCAD.Base.Vector( -obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, 0)) xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin scale = min((self.L-4*self.marge) / xmax, (self.H-4*self.marge) / ymax) if (not self.scale_auto) or (self.onedrawing): scale = self.scale if id_ == 0 or not self.onedrawing: # Init. FreeCAD.Console.PrintMessage('Dawing2d: init\n') self.TopX_H = self.marge*2 self.TopY_H = self.marge*2 TopX = self.TopX_H TopY = self.TopY_H self.TopX_H = self.TopX_H + xmax * scale + self.marge self.TopY_H = self.TopY_H self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge) self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) self.TopX_V = max(self.TopX_Vmax, self.TopX_V) self.TopY_V = self.marge * 2 elif self.onedrawing: if self.TopX_H + xmax * scale < self.L: if self.TopY_H + ymax * scale + self.marge*2 < self.H: # H Add at right on same horizontal line. FreeCAD.Console.PrintMessage('Dawing2d: horizontal\n') TopX = self.TopX_H TopY = self.TopY_H self.TopX_H = self.TopX_H + xmax * scale + self.marge self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge) self.TopX_Vmax = max(self.TopX_Hmax, self.TopX_Vmax) self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) self.TopX_V = max(self.TopX_Vmax, self.TopX_V) else: # # V Add at right on same horizontal line # FreeCAD.Console.PrintMessage('Dawing2d: vertival\n') if self.TopX_V + ymax * scale + 2 * self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H: Draft.rotate(obj, 90) Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0)) self.TopX_V = max(self.TopX_Vmax, self.TopX_V) TopX = self.TopX_V TopY = self.TopY_V self.TopX_V = self.TopX_V + ymax * scale + self.marge self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge) else: obj_l.append([obj, 'name']) return obj_l else: # H Carriage return. if (self.TopY_Hmax + ymax * scale + self.marge*2 < self.H): FreeCAD.Console.PrintMessage('Dawing2d: carriage return: '+str(self.TopY_H + ymax * scale)+' > '+str(self.H)+'\n') TopX = self.marge*2 TopY = self.TopY_Hmax self.TopX_H = TopX + xmax * scale + self.marge self.TopY_H = TopY self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H) self.TopY_Hmax = self.TopY_Hmax + ymax*scale+self.marge self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax) self.TopX_V = max(self.TopX_Vmax, self.TopX_V) else: # V Add at right on same horizontal line. FreeCAD.Console.PrintMessage('Dawing2d: vertical: ' + str(self.TopX_V) + ', ' + str(self.TopX_Vmax) + '\n') if self.TopX_V + ymax * scale + 2*self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H : Draft.rotate(obj, 90) Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0)) TopX = self.TopX_V TopY = self.TopY_V self.TopX_V = self.TopX_V + ymax * scale + self.marge self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge) else: obj_l.append([obj, 'name']) return obj_l page = FreeCAD.activeDocument().getObject(self.page_name) Text = FreeCAD.activeDocument().addObject('Drawing::FeatureViewAnnotation', objname + '_txt') Text.Text = objname Text.X = TopX + xmax / 2 * scale Text.Y = TopY + ymax / 2 * scale Text.Scale = 1 TopView = FreeCAD.activeDocument().addObject('Drawing::FeatureViewPart', 'TopView') TopView.Source = obj TopView.Direction = (0.0, 0.0, 1) TopView.Rotation = 0 TopView.X = TopX TopView.Y = TopY TopView.ShowHiddenLines = True TopView.Scale = scale page.addObject(TopView) page.addObject(Text) FreeCAD.activeDocument().recompute() return obj_l ##################################### # Dialog Box ##################################### fields = [['Group Name', 'Unfolding']] fields.append(['Scale', '1']) DialogBox = QtGui.QDialog() DialogBox.resize(250, 250) DialogBox.setWindowTitle('unfoldBox') la = QtGui.QVBoxLayout(DialogBox) # Input fields. for id_ in range(len(fields)): la.addWidget(QtGui.QLabel(fields[id_][0])) fields_l.append(QtGui.QLineEdit(fields[id_][1])) la.addWidget(fields_l[id_]) scale_check = QtGui.QCheckBox(DialogBox) scale_check.setObjectName('checkBox') scale_check.setChecked(True) la.addWidget(QtGui.QLabel('Scale auto')) la.addWidget(scale_check) a3_check = QtGui.QCheckBox(DialogBox) a3_check.setObjectName('checkBox') la.addWidget(QtGui.QLabel('A3 Format')) a3_check.setChecked(False) la.addWidget(a3_check) cartridge_check = QtGui.QCheckBox(DialogBox) cartridge_check.setObjectName('checkBox') la.addWidget(QtGui.QLabel('Cartridge')) cartridge_check.setChecked(False) la.addWidget(cartridge_check) onedrawing_check = QtGui.QCheckBox(DialogBox) onedrawing_check.setObjectName('checkBox') la.addWidget(QtGui.QLabel('Group drawings in page')) onedrawing_check.setChecked(True) la.addWidget(onedrawing_check) sewed_check = QtGui.QCheckBox(DialogBox) sewed_check.setObjectName('checkBox') la.addWidget(QtGui.QLabel('Sewed surfaces')) sewed_check.setChecked(True) la.addWidget(sewed_check) box = QtGui.QDialogButtonBox(DialogBox) box = QtGui.QDialogButtonBox(DialogBox) box.setOrientation(QtCore.Qt.Horizontal) box.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) la.addWidget(box) QtCore.QObject.connect(box, QtCore.SIGNAL('accepted()'), proceed) QtCore.QObject.connect(box, QtCore.SIGNAL('rejected()'), close) QtCore.QMetaObject.connectSlotsByName(DialogBox) DialogBox.show()