Stretch in 3D

Show off your FreeCAD projects here!
eason
Posts: 111
Joined: Thu Apr 09, 2015 2:40 am
Location: Taiwan

Stretch in 3D

Postby eason » Fri Nov 13, 2015 6:02 am

Hi ,
It just can stretch 3d objects.
It can sel many of objects.
It can't work without snap.
it just can one line to touch objects,when you select objects

How to use it ?

import this_py
this_py.showup()

1.showup
ss3d1.png
ss3d1.png (192.36 KiB) Viewed 10900 times
2.pick 2 point to choose the objects what you want to stretch.
ss3d2.png
ss3d2.png (194.83 KiB) Viewed 10900 times
ss3d3.png
ss3d3.png (225 KiB) Viewed 10900 times
3.next, pick 2 point to check the direction and distance.
ss3d4.png
ss3d4.png (233.67 KiB) Viewed 10900 times
ss3d5.png
ss3d5.png (229.26 KiB) Viewed 10900 times
I know there are many of bugs ..

I will make it to be perfact.

Maybe you can give some opinion.

Thanks!

Code: Select all

# -*- coding: utf-8 -*-
#####################################
#    3D                           
#    2015/10/05 11:35   
#          hahaha~
#####################################
import FreeCADGui, Part
import FreeCAD
import DraftVecUtils
import DraftTrackers
from PySide import QtCore, QtGui
from PySide.QtCore import QObject
from pivy.coin import *
from pivy import coin
import Draft
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_reobsel(object):
    def __init__(self):
        global LCD_CM,LCD_NM
        LCD_CM = []
        LCD_NM = []
        self.setupUi()
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.point = None
        self.p = None
        self.CLG = None
        self.presc = -1
        self.getobj()     
        self.aline()       
        self.c = self.view.addEventCallback("SoEvent",self.action)
    def action(self,info):
        global LCD_CM,LCD_NM,SSCM,movt,ONMIDOBJ,MD
        if self.stack: lastpoint = self.stack[-1]
        else: lastpoint = None
        self.point = FreeCADGui.Snapper.snap(info["Position"],lastpoint,info["ShiftDown"],info["ShiftDown"],True)  #snap
        #~ FreeCAD.Console.PrintMessage('\nself.point:'+str(self.point)) 
        if info["Type"] == "SoKeyboardEvent": 
            if info["Key"] == 'ESCAPE':  #  ESC
                self.reob()
        elif info["Type"] == "SoLocation2Event" : #    move
            if len(self.stack) == 1:
                p1 = [self.stack[-1][0],self.stack[-1][1],self.stack[-1][2]]
                p2 = [self.point[0],self.point[1],self.point[2]]
                diagonal = self.point.sub(self.stack[-1])
                p3 = self.stack[-1].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.v))
                p4 = self.stack[-1].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.u))
                p3 = [p3[0],p3[1],p3[2]]
                p4 = [p4[0],p4[1],p4[2]]
                pt = [p1,p3,p2,p4]
                self.coords1.point.setValues(pt)
                self.lines1.coordIndex.setValues(0,5,[0,1,2,3,0])
            if len(self.stack) == 3: 
                #~ prf('SSCM',SSCM)
                #~ for i in SSCM:
                    #~ FreeCADGui.ActiveDocument.getObject(i.Name).Visibility = False
                self.coords2.point.setValues([[self.stack[-1][0],self.stack[-1][1],self.stack[-1][2]],[self.point[0],self.point[1],self.point[2]]])
                self.lines2.coordIndex.setValues(0,2,[0,1])
                MD = self.point.sub(self.stack[-1])
                self.p.move(MD)
                self.DCL1.setText(str(round(MD[0],4)))
                self.DCL2.setText(str(round(MD[1],4)))
                self.DCL3.setText(str(round(MD[2],4)))
                self.DCL12.setText(str(round(MD.Length,4)))
                self.DCL12.setFocus()
                self.DCL12.selectAll()
        elif info["Type"] == "SoMouseButtonEvent":#   click
            if info["State"] == 'DOWN' and info["Button"] == "BUTTON1":#DOWN
                self.stack.append(self.point) 
                if len(self.stack) == 1: #point1
                    FreeCAD.Console.PrintMessage("\nplease pick 1 point!")
                elif len(self.stack) == 2: #point2
                    self.label9.setText(QtGui.QApplication.translate("Form", "pls pick 2 point ", None,QtGui.QApplication.UnicodeUTF8))
                    self.sg1.removeChild(self.no1) #remove
                    p1 = self.stack[0] # point1
                    p2 = self.stack[1] # point2
                    diagonal = self.stack[1].sub(self.stack[0])
                    p3 = self.stack[0].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.v))
                    p4 = self.stack[0].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.u))
                    FreeCAD.ActiveDocument.openTransaction("3D Stretch-cut") # undo
                    LCD_CM,LCD_NM = cutobj(p1,p3,p2,p4) # cut
                    FreeCAD.ActiveDocument.commitTransaction() # undo
                    self.presc = 0 # esc
                    SSCM = []
                    prf("LCD_CM",LCD_CM)
                    for i in LCD_CM:
                        for ii in i:
                            SSCM.append(ii)
                    prf('SSCM',SSCM)
                    for i in ONMIDOBJ:
                        SSCM.append(i)
                    self.p=DraftTrackers.ghostTracker(SSCM) # trackers  give my obj
                    self.p.on() # trackers   on !
                elif len(self.stack) == 4:
                    self.sg2.removeChild(self.no2) # close  line
                    self.precs = 1
                    movt = self.stack[-1].sub(self.stack[-2]) # move_distance
                    self.CKDS()
    def accept(self): # accept
        self.CKDS()
    def reject(self):  # cancel
        self.reob()
    def reob(self):#close
        global LCD_NM,LCD_CM,FACELIST
        self.sg1.removeChild(self.no1)
        self.sg2.removeChild(self.no2)
        if self.p: self.p.off() # close tracker
        FreeCADGui.Snapper.off()  #close snap
        FreeCAD.Console.PrintMessage("\nStretch  quit...!")
        self.view.removeEventCallback("SoEvent",self.c)  #close Observer
        prf('close self.c')
        FreeCADGui.Control.closeDialog()
        prf(self.presc)
        if self.presc == 0:
            prf('press ESC ... visibility => True')
            try:
                for ii in FACELIST:
                    prf('ii',ii)
                    FreeCADGui.ActiveDocument.getObject(ii[0].Name).Visibility = True
                    prf(ii[0].Name)
                prf("LCD_CM",LCD_CM[0][0].Name)
                prf("LCD_NM",LCD_NM[0][0].Name)
                for i in LCD_CM:
                    for ii in i:
                        FreeCAD.ActiveDocument.removeObject(ii.Name)
                for i in LCD_NM:
                    for ii in i:
                      FreeCAD.ActiveDocument.removeObject(ii.Name)
                prf("del ok..!")
            except:
                prf("DELERROR")
        close()
    def getobj(self):# sel 
        self.sg1 = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
        ma = coin.SoBaseColor()
        ma.rgb = (1,0,0)
        self.coords1 = coin.SoCoordinate3()
        self.lines1 = coin.SoIndexedLineSet()
        self.no1 = coin.SoSeparator()
        self.no1.addChild(self.coords1)
        self.no1.addChild(ma)
        self.no1.addChild(self.lines1)
        self.sg1.addChild(self.no1)
    def aline(self):# a line 
        self.sg2 = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
        ma = coin.SoBaseColor()
        ma.rgb = (0,0,1)
        self.coords2 = coin.SoCoordinate3()
        self.lines2 = coin.SoIndexedLineSet()
        self.no2 = coin.SoSeparator()
        self.no2.addChild(self.coords2)
        self.no2.addChild(ma)
        self.no2.addChild(self.lines2)
        self.sg2.addChild(self.no2)
    def setupUi(self):
        widget1 = QtGui.QWidget()
        widget1.setWindowTitle(QtGui.QApplication.translate("Form", "3D Stretch", None,QtGui.QApplication.UnicodeUTF8))
        
        self.layout = QtGui.QGridLayout(widget1)
        self.layout.setSpacing(5)
        self.layout.setColumnMinimumWidth(0,10)

        self.form = [widget1]
        self.getK = QtGui.QPushButton(widget1)
        self.getK.setObjectName(_fromUtf8("getK"))
        self.layout.addWidget(self.getK,1,0)

        self.form = [widget1]
        self.OK = QtGui.QPushButton(widget1)
        self.OK.setObjectName(_fromUtf8("OK"))
        self.layout.addWidget(self.OK,6,1)

        self.label1 = QtGui.QLabel(widget1)
        self.label1.setObjectName(_fromUtf8("label1"))
        self.layout.addWidget(self.label1,2,0)

        self.DCL1 = QtGui.QLineEdit(widget1)
        self.DCL1.setObjectName(_fromUtf8("DCL1"))
        self.layout.addWidget(self.DCL1,2,1)

        self.label2 = QtGui.QLabel(widget1)
        self.label2.setObjectName(_fromUtf8("label2"))
        self.layout.addWidget(self.label2,3,0)

        self.label = QtGui.QLabel(widget1)
        self.label.setObjectName(_fromUtf8("label"))
        self.layout.addWidget(self.label,5,0)

        self.DCL12 = QtGui.QLineEdit(widget1)
        self.DCL12.setObjectName(_fromUtf8("DCL12"))
        self.layout.addWidget(self.DCL12,5,1)
        
        self.DCL2 = QtGui.QLineEdit(widget1)
        self.DCL2.setObjectName(_fromUtf8("DCL2"))
        self.layout.addWidget(self.DCL2,3,1)

        self.label3 = QtGui.QLabel(widget1)
        self.label3.setObjectName(_fromUtf8("label3"))
        self.layout.addWidget(self.label3,4,0)

        self.label4 = QtGui.QLabel(widget1)
        self.label4.setObjectName(_fromUtf8("label4"))
        self.layout.addWidget(self.label4,6,0)

        self.label5 = QtGui.QLabel(widget1)
        self.label5.setObjectName(_fromUtf8("label5"))
        self.layout.addWidget(self.label5,8,0)

        self.label9 = QtGui.QLabel(widget1)
        self.label9.setObjectName(_fromUtf8("label9"))
        self.layout.addWidget(self.label9,9,0)


        self.DCL3 = QtGui.QLineEdit(widget1)
        self.DCL3.setObjectName(_fromUtf8("DCL3"))
        self.layout.addWidget(self.DCL3,4,1)

        QtCore.QObject.connect(self.OK, QtCore.SIGNAL("clicked()"), self.CKDS)
        QtCore.QObject.connect(self.getK, QtCore.SIGNAL("clicked()"), self.getKK)

        QtCore.QObject.connect(self.DCL12, QtCore.SIGNAL(_fromUtf8("editingFinished()")), self.norgetpos)

        self.DCL1.setText("0.00")
        self.DCL2.setText("0.00")
        self.DCL3.setText("0.00")
        self.DCL12.setText("0")
        self.DCL1.setEnabled(False)
        self.DCL2.setEnabled(False)
        self.DCL3.setEnabled(False)

        self.label.setText(QtGui.QApplication.translate("Form", "Distance:", None,QtGui.QApplication.UnicodeUTF8))
        self.label1.setText(QtGui.QApplication.translate("Form", "X Distance:", None,QtGui.QApplication.UnicodeUTF8))
        self.label2.setText(QtGui.QApplication.translate("Form", "Y Distance:", None,QtGui.QApplication.UnicodeUTF8))
        self.label3.setText(QtGui.QApplication.translate("Form", "Z Distance:", None,QtGui.QApplication.UnicodeUTF8))
        self.label9.setText(QtGui.QApplication.translate("Form", "pls sel obj", None,QtGui.QApplication.UnicodeUTF8))
        self.OK.setText(QtGui.QApplication.translate("reobsel", "move", None, QtGui.QApplication.UnicodeUTF8))
        self.getK.setText(QtGui.QApplication.translate("reobsel", "restart", None, QtGui.QApplication.UnicodeUTF8))
    def CKDS(self):
        global LCD_CM,LCD_NM,SSCM,ONMIDOBJ
        if LCD_CM == LCD_NM == []: return(errorDialog("please selection obj first!"))
        prf("GOGOGO")
        x=float(self.DCL1.text())
        y=float(self.DCL2.text())
        z=float(self.DCL3.text())
        mov = FreeCAD.Vector(x,y,z)
        FreeCAD.ActiveDocument.openTransaction("3D Stretch-move") # undo
        prf('ONMIDOBJ',ONMIDOBJ)
        for i in ONMIDOBJ:# move!
            Draft.move(i,mov,copy=False)
        ssobj(LCD_CM,LCD_NM,mov) # stretch!
        FreeCAD.ActiveDocument.commitTransaction() # undo
        self.reob()
    def getKK(self): # close and open
            self.reob()
            showup()
    def norgetpos(self):
        global MD
        
        d=float(self.DCL12.text())
        cd = MD.normalize()*d
        prf('cd',cd)
        self.DCL1.setText(str(round(float(cd[0]),4)))
        self.DCL2.setText(str(round(float(cd[1]),4)))
        self.DCL3.setText(str(round(float(cd[2]),4)))
        
def isBoxIntersection(s1,s2):
    b1=s1.BoundBox
    b2=s2.BoundBox
    if b1.intersect(b2):
        prf("isBoxIntersection True!!!!!!")
        return(True)
    elif b2.closestPoint(b1.Center).sub(b1.closestPoint(b2.Center)).Length < 0.0005:
        prf("isBoxIntersection True!!!!!!")
        return(True)
    else:
        prf("isBoxIntersection False")
        return(False)


def cutobj(a1=[],a2=[],a3=[],a4=[]): # give 4 vec ... make a ..Shell ... cut obj ... return 2 list...
    global name,lcolor,pcolor,scolor,mygroup,commonFace,FACELIST,DELII,ONMIDOBJ
    DELII = []
    prf('p1 = FreeCAD.Vector('+str(a1[0])+','+str(a1[1])+','+str(a1[2])+')')
    prf('p2 = FreeCAD.Vector('+str(a2[0])+','+str(a2[1])+','+str(a2[2])+')')
    prf('p3 = FreeCAD.Vector('+str(a3[0])+','+str(a3[1])+','+str(a3[2])+')')
    prf('p4 = FreeCAD.Vector('+str(a4[0])+','+str(a4[1])+','+str(a4[2])+')')
    if a1==a2==a3==a4==[]:
        a1=FreeCAD.Vector(10,0,0)
        a2=FreeCAD.Vector(-10,20,0)
        a3=FreeCAD.Vector(10,30,0)
        a4=FreeCAD.Vector(30,0,0)
    shape=Part.Face(Part.makePolygon([a1,a2,a3,a4], True)) # shape
    nor = shape.normalAt(0,0) # nor
    dd = 200 # nor**
    v1po = a1+nor*dd
    v2po = a2+nor*dd
    v3po = a3+nor*dd
    v4po = a4+nor*dd
    v1ne = a1-nor*dd
    v2ne = a2-nor*dd
    v3ne = a3-nor*dd
    v4ne = a4-nor*dd
    shape1=Part.Face(Part.makePolygon([v1po,v2po,v3po,v4po], True))
    shape2=Part.Face(Part.makePolygon([v1ne,v2ne,v3ne,v4ne], True))
    shape3=Part.Face(Part.makePolygon([v1po,v2po,v2ne,v1ne], True))
    shape4=Part.Face(Part.makePolygon([v2po,v3po,v3ne,v2ne], True))
    shape5=Part.Face(Part.makePolygon([v3po,v4po,v4ne,v3ne], True))
    shape6=Part.Face(Part.makePolygon([v1po,v4po,v4ne,v1ne], True))
    shape_list = [shape1,shape2,shape3,shape4,shape5,shape6]
    shell_shape=Part.Shell([shape1,shape5,shape3,shape4,shape6,shape2])
    BOXSHAPE = Part.makeSolid(shell_shape)
    shellPt = Part.Vertex(shell_shape.CenterOfMass)
    shape_sum = 0
    cutobj = None
    commonFace = None
    mygroup = []
    FACELIST = []
    ONMIDOBJ = []
    NUM=1
    NUM1=len(FreeCAD.ActiveDocument.Objects)
    bar_showup()
    for i in FreeCAD.ActiveDocument.Objects: # all obj
        QQ=0
        setvalue(NUM*100/NUM1)
        NUM+=1
        if QQ == 0:
            if FreeCADGui.ActiveDocument.getObject(i.Name).Visibility == True:
                try: 
                    for j in shape_list:
                        FreeCAD.Console.PrintMessage('\ni:'+str(i.Name)+'   j:'+str(j)+'  =>  '+str(len(i.Shape.common(j).Faces)))
                        if len(i.Shape.common(j).Faces) >= 1:
                            commonFace = i.Shape.common(j).Faces # Face 
                            cutobj = i
                            objbaseshape = j
                            shape_sum += 1
                            prf('objName',cutobj.Name)
                            TRA = FreeCADGui.ActiveDocument.getObject(cutobj.Name).Transparency   # get Transparency
                            scolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).ShapeColor  # get shape color
                            lcolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).LineColor  # get line color
                            pcolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).PointColor  # get point locor
                            try:
                                C_GRP = cutobj.GROUP
                                C_ID = cutobj.ID
                            except:
                                C_GRP = []
                                C_ID = []
                                prf("NO~~~group  id")
                            if cutobj.InList <> []:  # get group
                                groupname = cutobj.InList[0].Name
                                mygroup = FreeCAD.ActiveDocument.getObject(groupname)
                            name = cutobj.Label # get name
                            prf("Transparency",TRA)
                            prf('scolar',scolar)
                            prf('lcolar',lcolar)
                            prf('pcolar',pcolar)
                            prf('mygroup',mygroup)
                            prf('name',name)# cut)obj  Base_face  common_face  Transparency shape.. point line shape group group id
                            FACELIST.append([i,j,commonFace,TRA,scolar,lcolar,pcolar,mygroup,name,C_GRP,C_ID]) 
                    try: # find obj in mid
                        if i.Shape.common(BOXSHAPE).Area == i.Shape.Area: #in mid
                            ONMIDOBJ.append(i)
                            prf('Area SAME')
                        else:
                            prf('Area NOT SAME . . . !  ')
                    except:
                        prf('MID FIND ERROR...')
                except: prf('\nNo Shape.')
    if shape_sum == 0:
        return(errorDialog("GET NO OBJECTS!"))
    #find GROUP
    ###
    C_CM=[]
    C_NM=[]
    CMOBJLIST = []
    NMOBJLIST = []
    NUM=1
    NUM1=len(FACELIST)
    bar_showup()
    for i in FACELIST: # cut)obj  Base_face  common_face
        setvalue(NUM*100/NUM1)
        NUM+=1
        #   i[0] = cutobj
        #   i[1] = objbaseshape
        #   i[2] = commonFace
        objbase = mkObj(i[1])
        objnor = commonFace[0].normalAt(0,0) # obj nor 
        #Extrude..
        EXT = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrude")
        EXT.Base = objbase
        EXT.Dir = objnor*0.0001*-1
        EXT.Solid = (True)
        FreeCAD.ActiveDocument.recompute()
        #CUT
        mycut = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut")
        mycut.Base = i[0]
        mycut.Tool = EXT
        FreeCAD.ActiveDocument.recompute()
        DOW = Draft.downgrade([mycut],delete=True)
        prf('DOW',DOW   ) # cut obj
        FreeCAD.ActiveDocument.recompute()
        T_CM=[]
        T_NM=[]
        for ii in DOW[0]:
            prf('common der Face:',len(BOXSHAPE.common(ii.Shape).Solids))
            if len(BOXSHAPE.common(ii.Shape).Solids) ==1:
                T_CM.append(ii) # MOVE
                prf("MOVE")
            else:
                T_NM.append(ii)# NO MOVE
                prf("NO MOVE")
        C_CM.append(T_CM)
        C_NM.append(T_NM)
        for ii in DOW[0]:
            FreeCADGui.ActiveDocument.getObject(ii.Name).Transparency = i[3]   # give Transparency
            FreeCADGui.ActiveDocument.getObject(ii.Name).ShapeColor = i[4]    # give shape color
            FreeCADGui.ActiveDocument.getObject(ii.Name).LineColor = i[5]      # give line color
            FreeCADGui.ActiveDocument.getObject(ii.Name).PointColor = i[6]     # give point locor
        prf('del objbase',objbase.Name)
        FreeCAD.ActiveDocument.removeObject(objbase.Name)
        #~ prf("i[0].Name",i[0].Name)
        DELII.append(i[0].Name) # find the objs will stretch
        prf("EXT.Name",EXT.Name)
        FreeCAD.ActiveDocument.removeObject(EXT.Name) # remove 
        prf("C_CM",C_CM)
        prf("C_NM",C_NM)
    close()
    return(C_CM,C_NM)

def ssobj(CO_CM,CO_NM,MOV):
    global name,lcolor,pcolor,scolor,mygroup,commonFace,FACELIST,DELII
    prf("FACELIST",FACELIST)
    num=0
    DELLIST=[]
    KED = 0
    LENN = MOV.Length
    LEN = MOV.Length+0.0015
    objnor = MOV.normalize() # obj nor 
    MMOV = objnor*LENN
    bar_showup()
    NUM=1
    NUM1=len(FACELIST)
    for ii in FACELIST: # N  [  [obj,obj,[face,face,face],tra,pc,lc,sc,group,name,grp,id] , [...] , [...] , [...]  ]
        setvalue(NUM*100/NUM1)
        NUM+=1
        CLOUD9=[] # obj need to Fuse
        TPA=[]
        for i in ii[2]:# commonface 
            TPA.append(mkObj(i))
            AEXT = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrude") # Face __ Extrude
            AEXT.Base = TPA[-1]
            AEXT.Dir = objnor*(LEN)
            AEXT.Solid = (True)
            FreeCAD.ActiveDocument.recompute()
            for j in CO_NM[num]: # Judge cut or fuse
                if AEXT.Shape.common(j.Shape).Area > 0.1:
                    KED = 1
            FreeCAD.ActiveDocument.recompute()
            CLOUD9.append(AEXT)
            Draft.move(AEXT,objnor*-0.0005,copy=False)#stretch obj avoid ..0.0005..
            FreeCAD.ActiveDocument.recompute()
        # CM obj move ..
        Draft.move(CO_CM[num],MMOV,copy=False)
        prf('MOV',MOV)
        if KED == 1:    #  cut
            prf("cut")
            if len(CLOUD9) > 1:
                MuCut = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","myEXXXX")
                MuCut.Shapes = CLOUD9
                FreeCAD.ActiveDocument.recompute()
            else:
                MuCut = CLOUD9[0]
                MuCut.Label = 'myEXXXX'
            DELLIST.append(MuCut.Name)
            if len(CO_NM[num]) > 1: # CUT BASE
                SECut = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","CUTBAS")
                SECut.Shapes = CO_NM[num]
                FreeCAD.ActiveDocument.recompute()
            else:
                SECut = CO_NM[num][0]
                SECut.Label = 'CUTBASE'
            DELLIST.append(SECut.Name)
            C9Cut = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut") #cut!
            C9Cut.Base = SECut
            C9Cut.Tool = MuCut
            DELLIST.append(C9Cut.Name)
            Draft.move(C9Cut,objnor*-0.0012,copy=False)
            FreeCAD.ActiveDocument.recompute()
            COO = [] # fuse_obj
            COO.append(C9Cut)
            for k in CO_CM[num]:
                COO.append(k)
            Mu = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","Fusion")
            Mu.Shapes = COO
            FreeCAD.ActiveDocument.recompute()
            #~ if ii [9] <> []:
                #~ from GsCad.c1_std import addpro
                #~ Mui = addpro.addpro(Mui,ii[8],ii[9],ii[10],'    ',[[0,0,0]],ii[5],ii[6],ii[4])[0]
            #~ else:
            Mui = mkObj(Mu.Shape)
            Mui.Label = ii[8]    #name
            if ii[7]: mygroup.addObject(Mui)  #grp
            FreeCADGui.ActiveDocument.getObject(Mui.Name).Transparency = ii[3]   # Transparency
            FreeCADGui.ActiveDocument.getObject(Mui.Name).ShapeColor = ii[4]  # shape
            FreeCADGui.ActiveDocument.getObject(Mui.Name).LineColor = ii[5]      # line
            FreeCADGui.ActiveDocument.getObject(Mui.Name).PointColor = ii[6]   # point
            
            DELLIST.append(Mu.Name) # fuse_obj
            for iii in CO_NM[num]:
                CLOUD9.append(iii)
            for iii in CO_CM[num]:
                CLOUD9.append(iii)
            for ww in CLOUD9:
                DELLIST.append(ww.Name)
            for ww in TPA:
                DELLIST.append(ww.Name) # face
            num+=1
        else:    #  stretch
            prf("stretch")
            for i in CO_NM[num]:
                CLOUD9.append(i)
            for i in CO_CM[num]:
                CLOUD9.append(i)
            Mu = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","Fusion")
            Mu.Shapes = CLOUD9
            FreeCAD.ActiveDocument.recompute()
            Mui = mkObj(Mu.Shape)
            #~ if ii [9] <> []:
                #~ from GsCad.c1_std import addpro
                #~ Mui = addpro.addpro(Mui,ii[8],ii[9],ii[10],'    ',[[0,0,0]],ii[5],ii[6],ii[4])[0]
            #~ else:
            Mui.Label = ii[8]  #name
            if ii[7]: mygroup.addObject(Mui)  # grp
            FreeCADGui.ActiveDocument.getObject(Mui.Name).Transparency = ii[3]   # Transparency
            FreeCADGui.ActiveDocument.getObject(Mui.Name).ShapeColor = ii[4]  # shape
            FreeCADGui.ActiveDocument.getObject(Mui.Name).LineColor = ii[5]      # line
            FreeCADGui.ActiveDocument.getObject(Mui.Name).PointColor = ii[6]   # point

            DELLIST.append(Mu.Name) # fuse obj
            for ww in TPA:
                DELLIST.append(ww.Name) # face
            for ww in CLOUD9:
                DELLIST.append(ww.Name) # face obj_A obj_B
            num+=1
    close()
    prf("DELLIST",DELLIST)
    for i in DELLIST:
        try:
            FreeCAD.ActiveDocument.removeObject(i)
        except:
            prf("DEL repeat!")
    prf("DELII",DELII)
    for i in DELII:
        try: FreeCAD.ActiveDocument.removeObject(i)
        except: prf("DELII no",i)
def showup():
    global reobsel
    reobsel = Ui_reobsel()
    FreeCADGui.Control.showDialog(reobsel)

def isPtOnEdge(pt,edge) : # find is point on edge
    v = Part.Vertex(pt)
    d = v.distToShape(edge)
    if d:
        if d[0] < 0.01:
            return True
    return False

def mkObj(shape):  # make obj
    obj = FreeCAD.ActiveDocument.addObject("Part::Feature",'Temp')
    obj.Shape = shape
    FreeCAD.ActiveDocument.recompute()
    return(obj)

def errorDialog(msg): # message
    unicode_str =  unicode(msg,'utf-8')
    diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error MessageBox', unicode_str)
    diag.setWindowModality(QtCore.Qt.ApplicationModal)
    diag.exec_()

def prf(m,p=0):
    if p==0: FreeCAD.Console.PrintMessage('\n'+str(m))
    else: FreeCAD.Console.PrintMessage('\n'+str(m)+':'+str(p))


class Ui_Bar():
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(240, 138)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.progressBar = QtGui.QProgressBar(self.centralWidget)
        self.progressBar.setGeometry(QtCore.QRect(10, 40, 211, 23))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.label = QtGui.QLabel(self.centralWidget)
        self.label.setGeometry(QtCore.QRect(30, 10, 267, 17))
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 240, 25))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        screen=QtGui.QDesktopWidget().screenGeometry()
        size=MainWindow.geometry()
        MainWindow.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "A progress bar", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("MainWindow", "please wait...", None, QtGui.QApplication.UnicodeUTF8))

def close():
    bbbarui.close()

def setvalue(v):
    Barui.progressBar.setProperty("value", v)



bbbarui = QtGui.QMainWindow()
Barui = Ui_Bar()
def  bar_showup():
    Barui.setupUi(bbbarui)
    bbbarui.show()


User avatar
yorik
Site Admin
Posts: 10725
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Stretch in 3D

Postby yorik » Fri Nov 13, 2015 5:45 pm

Wow, nice! I had plans to do something like that too ( issue #1163 ) but never had time to start...

I'll have a look at this ASAP!
cox
Posts: 957
Joined: Wed Nov 26, 2014 11:37 pm

Re: Stretch in 3D

Postby cox » Fri Nov 13, 2015 10:51 pm

Cool, eason
Nice work, and thanks for sharing
Godspeed on your journey for perfection :D
Need help? Feel free to ask, but please read the guidelines first
godblessfq
Posts: 94
Joined: Fri Jul 17, 2015 7:40 pm

Re: Stretch in 3D

Postby godblessfq » Thu Nov 26, 2015 8:38 pm

Looks like the sychronous modelling in solid edge. It would be nice to add position control of sketch mapped to faces parallel to the stretch direction, such as bottom alligned, centered and top aligned.
Thank you for sharing.
eason
Posts: 111
Joined: Thu Apr 09, 2015 2:40 am
Location: Taiwan

Re: Stretch in 3D

Postby eason » Thu Jun 02, 2016 7:24 am

Hi,
Here is version 2.0
  1. Add progress bar.
  • You can select what you want to stretch.
  • You can Select many objects.

Code: Select all

# -*- coding: utf-8 -*-
#####################################
#    3D拉昇功能                      #
#    2015/10/05 11:35               #
#               version 2.0             #
#           by    Eason               #
#####################################
import FreeCADGui, Part,FreeCAD,DraftVecUtils,DraftTrackers,Draft
import FreeCADGui as Gui
from PySide import QtCore, QtGui
from PySide.QtCore import QObject
from GsCad.fc_cmd import view
from pivy import coin
global FACELIST , linkobj
linkobj = []
FACELIST = []
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

# bar

global Barui
value = 0

class Ui_Bar():
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(240, 138)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.progressBar = QtGui.QProgressBar(self.centralWidget)
        self.progressBar.setGeometry(QtCore.QRect(10, 40, 211, 23))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.label = QtGui.QLabel(self.centralWidget)
        self.label.setGeometry(QtCore.QRect(30, 10, 267, 17))
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 240, 25))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        screen=QtGui.QDesktopWidget().screenGeometry()
        size=MainWindow.geometry()
        MainWindow.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "progress bar", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("MainWindow", "Program execution. Please wait ...", None, QtGui.QApplication.UnicodeUTF8))

def bar_close():
    bbbarui.close()

def bar_setvalue(v):
    Barui.progressBar.setProperty("value", v)



bbbarui = QtGui.QMainWindow()
Barui = Ui_Bar()
def  bar_showup():
    Barui.setupUi(bbbarui)
    bbbarui.show()

# bar

# view

global sg,ma,coords,lines,no
def view_open():
    global sg,ma,coords,lines,no
    '''
    開啟動畫效果
    '''
    sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
    ma = coin.SoBaseColor()
    ma.rgb = (1.0,0.0,1.0)
    coords = coin.SoCoordinate3()
    lines = coin.SoIndexedLineSet()
    no = coin.SoSeparator()
    no.addChild(coords)
    no.addChild(ma)
    no.addChild(lines)
    sg.addChild(no)

def view_close():
    global sg,coords,lines,no,ma
    '''
    關掉動畫效果
    '''
    
    no.removeChild(coords)
    no.removeChild(lines)
    no.removeChild(ma)
    #sg.removeChild(coords)

def view_set(pts,num):
    global sg,ma,coords,lines,no
    '''
    設定線 set(pts,num)
    pts: [ [p1] , [p2] , [p3] ....]
    num: [0,1,-1,2,3 ....]
    -1表示隔開
    0,1 表示連接0&1兩點的線段
    '''
    coords.point.setValues(pts)
    lines.coordIndex.setValues(0,len(num),num)

def view_clear():
    list1 = []
    list2 = []
    for i in range(100):
        list1.append(0)
        list2.append([0,0,0])
    coords.point.setValues(list2)
    lines.coordIndex.setValues(0,len(list1),list1)

# view

class Ui_reobsel(object):
    def __init__(self):
        global LCD_CM,LCD_NM,linkobj,change_sel_mode,change_sel_mode,grid_mode
        change_sel_mode = 1 # 選取物件模式
        linkobj = []
        LCD_CM = []
        LCD_NM = []
        self.setupUi()
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        view_open()
        self.point = None
        self.p = None
        self.CLG = None
        self.presc = -1
        self.c = self.view.addEventCallback("SoEvent",self.action)
    def action(self,info):
        global linkobj
        global LCD_CM,LCD_NM,SSCM,movt,ONMIDOBJ,MD,change_sel_mode
        if self.stack:
            if len(self.stack) == 3:
                lastpoint = self.stack[-1]
            else:
                lastpoint = None
        else: 
            lastpoint = None
        if change_sel_mode == 2: # 選取物件完才執行
            self.point = FreeCADGui.Snapper.snap(info["Position"],lastpoint,info["CtrlDown"],info["ShiftDown"],True)  #鎖點
        if info["Type"] == "SoKeyboardEvent":   #  鍵盤按下事件
            if info["State"] == 'UP':
                if info["Key"] == 'RETURN' or info["Key"] == 'PAD_ENTER':  #  按下ENTER
                    if change_sel_mode == 1 :
                        prf('ENTER UP')
                        self.label12.setText(QtGui.QApplication.translate("Form", "", None,QtGui.QApplication.UnicodeUTF8))
                        self.label9.setText(QtGui.QApplication.translate("Form", "<font color=red style='font-size:14pt'><b>Pleasr selete the range</b></font>", None,QtGui.QApplication.UnicodeUTF8))
                        change_sel_mode += 1
            if info["Key"] == 'ESCAPE':  #  按下ESC關掉所有東西
                self.reob()
        elif info["Type"] == "SoLocation2Event" : #  滑鼠移動事件   move
            if len(self.stack) == 1:  #框框示意圖
                p1 = [self.stack[-1][0],self.stack[-1][1],self.stack[-1][2]]
                p2 = [self.point[0],self.point[1],self.point[2]]
                diagonal = self.point.sub(self.stack[-1])
                p3 = self.stack[-1].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.v))
                p4 = self.stack[-1].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.u))
                p3 = [p3[0],p3[1],p3[2]]
                p4 = [p4[0],p4[1],p4[2]]
                pt = [p1,p3,p2,p4]
                view_set(pt,[0,1,2,3,0])
            if len(self.stack) == 3: #拉昇示意圖
                pts=[[self.stack[-1][0],self.stack[-1][1],self.stack[-1][2]],[self.point[0],self.point[1],self.point[2]]]
                view_set(pts,[0,1])
                MD = self.point.sub(self.stack[-1])
                self.p.move(MD)
                self.DCL1.setText(str(round(MD[0],4)))
                self.DCL2.setText(str(round(MD[1],4)))
                self.DCL3.setText(str(round(MD[2],4)))
                self.DCL12.setText(str(round(MD.Length,4)))
                self.DCL12.setFocus()
                self.DCL12.selectAll()
        elif info["Type"] == "SoMouseButtonEvent":#  滑鼠點擊事件  click
            if change_sel_mode == 2: # 選取物件完才執行
                if info["State"] == 'DOWN' and info["Button"] == "BUTTON1":#滑鼠DOWN下去
                    self.stack.append(self.point)  #每點一下 都會把點紀錄到self.stack
                    if len(self.stack) == 1: #點第一下
                        FreeCAD.Console.PrintMessage("\n點第一點!")
                    elif len(self.stack) == 2: #點第二下
                        view_clear()
                        FreeCAD.Console.PrintMessage("\n框選完畢")
                        self.label9.setText(QtGui.QApplication.translate("Form", "<font color=red style='font-size:14pt'><b>Starting stretch!</b></font>", None,QtGui.QApplication.UnicodeUTF8))
                        #~ self.sg1.removeChild(self.no1) #移除框框效果
                        p1 = self.stack[0] # 第一點
                        p2 = self.stack[1] # 第二點
                        diagonal = self.stack[1].sub(self.stack[0])
                        p3 = self.stack[0].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.v)) # 計算框框兩點
                        p4 = self.stack[0].add(DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.u)) # 計算框框兩點
                        FreeCAD.ActiveDocument.openTransaction("3D拉昇-切割") # undo
                        LCD_CM,LCD_NM = cutobj(p1,p3,p2,p4) # 切割物件
                        FreeCAD.ActiveDocument.commitTransaction() # undo
                        if LCD_CM == LCD_NM == 0: # 沒找到物件 從開
                            self.reob()
                            showup()
                        else:
                            self.presc = 0
                            SSCM = []
                            prf("LCD_CM",LCD_CM)
                            for i in LCD_CM:
                                for ii in i:
                                    SSCM.append(ii)
                            prf('SSCM',SSCM)
                            for i in ONMIDOBJ:
                                SSCM.append(i)
                            prf('...ok!')
                            self.p=DraftTrackers.ghostTracker(SSCM) # 動畫效果..移動物件
                            self.p.on() # 啟動動畫效果
                    elif len(self.stack) == 4:
                        #~ self.sg2.removeChild(self.no2) # 結束動畫效果..線
                        #~ self.precs = 1
                        movt = self.stack[-1].sub(self.stack[-2]) # 移動量
                        self.label9.setText(QtGui.QApplication.translate("Form", "<font color=red style='font-size:14pt'><b>Please click 'OK' to finish</b></font>", None,QtGui.QApplication.UnicodeUTF8))
    def accept(self): # 確定
        global change_sel_mode
        if change_sel_mode == 2:
            self.CKDS()
        if change_sel_mode == 1:
            prf('ENTER UP')
            self.label12.setText(QtGui.QApplication.translate("Form", "", None,QtGui.QApplication.UnicodeUTF8))
            self.label9.setText(QtGui.QApplication.translate("Form", "<font color=red style='font-size:14pt'><b>Please Select the range what you want to stretch.</b></font>", None,QtGui.QApplication.UnicodeUTF8))
            change_sel_mode += 1
    def reject(self):  # 取消
        self.reob()
    def reob(self):#通通關掉
        global LCD_NM,LCD_CM,FACELIST , StaSel
        #~ self.sg1.removeChild(self.no1)
        #~ self.sg2.removeChild(self.no2)
        if self.p: self.p.off() # 結束動畫效果..移動物件
        view_close()
        FreeCADGui.Snapper.off()  #鎖點解除
        FreeCAD.Console.PrintMessage("\n拉昇結束...!")
        self.view.removeEventCallback("SoEvent",self.c)  #關掉Observer
        prf('close self.c')
        FreeCADGui.Control.closeDialog()
        #~ FreeCADGui.Selection.removeObserver(StaSel)
        if self.presc == -1: prf('沒選東西')
        if self.presc == 0:
            prf('press ESC ... visibility => True')
    def showobj(self):
        Gui.Selection.clearSelection()
        obj=FreeCAD.ActiveDocument.getObjectsByLabel(str(self.listins.currentItem().text()))
        Gui.Selection.addSelection(obj[0])
    def setupUi(self):

        widget1 = QtGui.QWidget()
        widget1.setWindowTitle(QtGui.QApplication.translate("Form", "3D Stretch", None,QtGui.QApplication.UnicodeUTF8))

        self.layout = QtGui.QGridLayout(widget1)
        self.layout.setSpacing(5)
        self.layout.setColumnMinimumWidth(0,10)

        self.form = [widget1]

        self.label1 = QtGui.QLabel(widget1)
        self.label1.setObjectName(_fromUtf8("label1"))
        self.layout.addWidget(self.label1,2,0)

        self.DCL1 = QtGui.QLineEdit(widget1)
        self.DCL1.setObjectName(_fromUtf8("DCL1"))
        self.layout.addWidget(self.DCL1,2,1)

        self.label2 = QtGui.QLabel(widget1)
        self.label2.setObjectName(_fromUtf8("label2"))
        self.layout.addWidget(self.label2,3,0)

        self.label = QtGui.QLabel(widget1)
        self.label.setObjectName(_fromUtf8("label"))
        self.layout.addWidget(self.label,5,0)

        self.DCL12 = QtGui.QLineEdit(widget1)
        self.DCL12.setObjectName(_fromUtf8("DCL12"))
        self.layout.addWidget(self.DCL12,5,1)
        
        self.DCL2 = QtGui.QLineEdit(widget1)
        self.DCL2.setObjectName(_fromUtf8("DCL2"))
        self.layout.addWidget(self.DCL2,3,1)

        self.label3 = QtGui.QLabel(widget1)
        self.label3.setObjectName(_fromUtf8("label3"))
        self.layout.addWidget(self.label3,4,0)

        self.label9 = QtGui.QLabel(widget1)
        self.label9.setObjectName(_fromUtf8("label9"))
        self.layout.addWidget(self.label9,9,0)

        self.DCL3 = QtGui.QLineEdit(widget1)
        self.DCL3.setObjectName(_fromUtf8("DCL3"))
        self.layout.addWidget(self.DCL3,4,1)

        self.label10 = QtGui.QLabel(widget1)
        self.label10.setObjectName(_fromUtf8("label10"))
        self.layout.addWidget(self.label10,6,0)

        self.label11 = QtGui.QLabel(widget1)
        self.label11.setObjectName(_fromUtf8("label11"))
        self.layout.addWidget(self.label11,6,1)

        self.label12 = QtGui.QLabel(widget1)
        self.label12.setObjectName(_fromUtf8("label12"))
        self.layout.addWidget(self.label12,12,1)

        self.listins = QtGui.QListWidget(widget1) # 放物件
        self.listins.setObjectName(_fromUtf8("listins"))
        self.listins.setFixedWidth(115)
        self.layout.addWidget(self.listins,12,0)

        self.sel1 = QtGui.QPushButton(widget1) # 選取
        self.sel1.setObjectName(_fromUtf8("sel1"))
        self.layout.addWidget(self.sel1,10,0)

        self.sel2 = QtGui.QPushButton(widget1) # 刪除
        self.sel2.setObjectName(_fromUtf8("sel2"))
        self.layout.addWidget(self.sel2,10,1)

        self.sel3 = QtGui.QPushButton(widget1) # 顯示
        self.sel3.setObjectName(_fromUtf8("sel3"))
        self.layout.addWidget(self.sel3,11,0)

        self.sel4 = QtGui.QPushButton(widget1) # 取消
        self.sel4.setObjectName(_fromUtf8("sel4"))
        self.layout.addWidget(self.sel4,11,1)

        QtCore.QObject.connect(self.sel1, QtCore.SIGNAL("clicked()"), self.addsel1)
        QtCore.QObject.connect(self.sel2, QtCore.SIGNAL("clicked()"), self.addsel2)
        QtCore.QObject.connect(self.sel3, QtCore.SIGNAL("clicked()"), self.addsel3)
        QtCore.QObject.connect(self.sel4, QtCore.SIGNAL("clicked()"), self.addsel4)
        QtCore.QObject.connect(self.listins, QtCore.SIGNAL("clicked(QModelIndex)"), self.showobj)

        QtCore.QObject.connect(self.DCL12, QtCore.SIGNAL(_fromUtf8("editingFinished()")), self.norgetpos)

        self.DCL1.setText("0.0000")
        self.DCL2.setText("0.0000")
        self.DCL3.setText("0.0000")
        self.DCL12.setText("0.0000")
        self.DCL1.setEnabled(False)
        self.DCL2.setEnabled(False)
        self.DCL3.setEnabled(False)

        self.sel1.setText(QtGui.QApplication.translate("Form", "Selsct", None,QtGui.QApplication.UnicodeUTF8))
        self.sel2.setText(QtGui.QApplication.translate("Form", "Delete", None,QtGui.QApplication.UnicodeUTF8))
        self.sel3.setText(QtGui.QApplication.translate("Form", "Display", None,QtGui.QApplication.UnicodeUTF8))
        self.sel4.setText(QtGui.QApplication.translate("Form", "Delete all", None,QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("Form", "distance:", None,QtGui.QApplication.UnicodeUTF8))
        self.label1.setText(QtGui.QApplication.translate("Form", "Global X:", None,QtGui.QApplication.UnicodeUTF8))
        self.label2.setText(QtGui.QApplication.translate("Form", "Global Y:", None,QtGui.QApplication.UnicodeUTF8))
        self.label3.setText(QtGui.QApplication.translate("Form", "Global Z:", None,QtGui.QApplication.UnicodeUTF8))
        self.label9.setText(QtGui.QApplication.translate("Form", "<font color=red style='font-size:14pt'><b>Please select objects</b></font>", None,QtGui.QApplication.UnicodeUTF8))
        self.label10.setText(QtGui.QApplication.translate("Form", "<font color=blue style='font-size:14pt'><b>——————</b></font>", None,QtGui.QApplication.UnicodeUTF8))
        self.label11.setText(QtGui.QApplication.translate("Form", "<font color=blue style='font-size:14pt'><b>————————</b></font>", None,QtGui.QApplication.UnicodeUTF8))
        self.label12.setText(QtGui.QApplication.translate("Form", "\
1.Check your working plane!\n2.Click objects you want to stretch.\n\
3.Click 'Select'.\n4.Click Enter to start.\n\
PS.If you click Enter without seleting anything..\nAll objects selected by default!"\
        , None,QtGui.QApplication.UnicodeUTF8))
        #~ self.OK.setText(QtGui.QApplication.translate("reobsel", "設定工作面", None, QtGui.QApplication.UnicodeUTF8))
    def addsel1(self): # 選取
        global linkobj
        if change_sel_mode == 1: # 選物件
            sel = Gui.Selection.getSelection()
            for i in sel:
                if i not in linkobj:
                    linkobj.append(i)
            self.listins.clear()
            for i in linkobj:
                self.listins.addItem(str(i.Label))
                
            for i in linkobj:
                FreeCADGui.Selection.addSelection(i)
    def addsel2(self): # 刪除
        global linkobj
        if change_sel_mode == 1: # 選物件
            sel = Gui.Selection.getSelection()
            for i in sel:
                if i in linkobj:
                    linkobj.remove(i)
            self.listins.clear()
            for i in linkobj:
                self.listins.addItem(str(i.Label))
            Gui.Selection.clearSelection()
            #for i in linkobj:
                #FreeCADGui.Selection.addSelection(i)  #慧芸要求不需顯示
    def addsel3(self): # 顯示
        global linkobj
        if change_sel_mode == 1: # 選物件
            FreeCADGui.Selection.clearSelection()
            for i in linkobj:
                FreeCADGui.Selection.addSelection(i)
    def addsel4(self): # 取消
        global linkobj
        if change_sel_mode == 1: # 選物件
            FreeCADGui.Selection.clearSelection()
            self.listins.clear()
    def setgrid(self): # 設定工作面
        global grid_mode
        if grid_mode == 0:
            grid_mode = 1
        else:
            grid_mode = 0
            if len(FreeCADGui.Selection.getSelection()) == 0:
                errorDialog('請選擇一個面!')
            else:
                sel = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0]
                if issubclass(type(sel),Part.Face):
                    FreeCAD.DraftWorkingPlane.alignToPointAndAxis()
                    FreeCADGui.Snapper.setGrid()
                else:
                    errorDialog('請選面!')
    def CKDS(self):
        global LCD_CM,LCD_NM,SSCM,ONMIDOBJ
        if LCD_CM == LCD_NM == []: return(errorDialog("請先選擇物件!"))
        x=float(self.DCL1.text())
        y=float(self.DCL2.text())
        z=float(self.DCL3.text())
        mov = FreeCAD.Vector(x,y,z)
        FreeCAD.ActiveDocument.openTransaction("3D拉昇-移動") # undo
        for i in ONMIDOBJ:# 移動!
            Draft.move(i,mov,copy=False)
        FreeCAD.ActiveDocument.recompute()
        ssobj(LCD_CM,LCD_NM,mov) # 拉昇!
        FreeCAD.ActiveDocument.recompute()
        FreeCAD.ActiveDocument.commitTransaction() # undo
        self.reob()
    def getKK(self): # 關掉在開
            self.reob()
            showup()
    def norgetpos(self):
        global MD
        
        d=float(self.DCL12.text())
        cd = MD.normalize()*d
        prf('cd',cd)
        self.DCL1.setText(str(round(float(cd[0]),4)))
        self.DCL2.setText(str(round(float(cd[1]),4)))
        self.DCL3.setText(str(round(float(cd[2]),4)))

def isBoxIntersection(s1,s2):
    b1=s1.BoundBox
    b2=s2.BoundBox
    if b1.intersect(b2):
        prf("isBoxIntersection True!!!!!!")
        return(True)
    elif b2.closestPoint(b1.Center).sub(b1.closestPoint(b2.Center)).Length < 0.0005:
        prf("isBoxIntersection True!!!!!!")
        return(True)
    else:
        prf("isBoxIntersection False")
        return(False)


def cutobj(a1=[],a2=[],a3=[],a4=[]): # 給4個座標 ... 畫出一個Shell ... 切割物件 ... 返回兩個物件
    global name,lcolor,pcolor,scolor,mygroup,commonFace,FACELIST,DELII,ONMIDOBJ,linkobj,cutline
    DELII = []
    prf('p1 = FreeCAD.Vector('+str(a1[0])+','+str(a1[1])+','+str(a1[2])+')')
    prf('p2 = FreeCAD.Vector('+str(a2[0])+','+str(a2[1])+','+str(a2[2])+')')
    prf('p3 = FreeCAD.Vector('+str(a3[0])+','+str(a3[1])+','+str(a3[2])+')')
    prf('p4 = FreeCAD.Vector('+str(a4[0])+','+str(a4[1])+','+str(a4[2])+')')
    if a1==a2==a3==a4==[]:
        a1=FreeCAD.Vector(10,0,0)
        a2=FreeCAD.Vector(-10,20,0)
        a3=FreeCAD.Vector(10,30,0)
        a4=FreeCAD.Vector(30,0,0)
    shape=Part.Face(Part.makePolygon([a1,a2,a3,a4], True)) # shape
    nor = shape.normalAt(0,0) # nor
    dd = 200 # nor向量加成
    v1po = a1+nor*dd
    v2po = a2+nor*dd
    v3po = a3+nor*dd
    v4po = a4+nor*dd
    v1ne = a1-nor*dd
    v2ne = a2-nor*dd
    v3ne = a3-nor*dd
    v4ne = a4-nor*dd
    shape1=Part.Face(Part.makePolygon([v1po,v2po,v3po,v4po], True))
    shape2=Part.Face(Part.makePolygon([v1ne,v2ne,v3ne,v4ne], True))
    shape3=Part.Face(Part.makePolygon([v1po,v2po,v2ne,v1ne], True))
    shape4=Part.Face(Part.makePolygon([v2po,v3po,v3ne,v2ne], True))
    shape5=Part.Face(Part.makePolygon([v3po,v4po,v4ne,v3ne], True))
    shape6=Part.Face(Part.makePolygon([v1po,v4po,v4ne,v1ne], True))
    shape_list = [shape1,shape2,shape3,shape4,shape5,shape6]
    shell_shape=Part.Shell([shape1,shape5,shape3,shape4,shape6,shape2])
    
    #~ Part.show(shell_shape)
    #~ BOX_W = v1po.sub(v2po).Length
    #~ BOX_L = v2po.sub(v3po).Length
    #~ BOX_H = v1po.sub(v1ne).Length
    #~ BOX_P = (a1+a2+a3+a4)*0.25-nor*dd+a2.sub(a1)*0.5+a3.sub(a2)*0.5

    #~ BOX_D = nor
    #~ BOXSHAPE = Part.makeBox(BOX_L,BOX_W,BOX_H,BOX_P,BOX_D)
    BOXSHAPE = Part.makeSolid(shell_shape)
    #~ Part.show(BOXSHAPE)
    shellPt = Part.Vertex(shell_shape.CenterOfMass)
    shape_sum = 0
    cutobj = None
    commonFace = None
    mygroup = []
    FACELIST = []
    ONMIDOBJ = []
    NUM=1
    NUM1=len(FreeCAD.ActiveDocument.Objects)
    cutline = []
    bar_showup()
    if linkobj == []:
        allOBJ = FreeCAD.ActiveDocument.Objects
    else:
        allOBJ = linkobj
    for i in allOBJ: # 全部的物件
        sel_line_up2 = 0
        QQ=0
        bar_setvalue(NUM*100/NUM1)
        NUM+=1
        if QQ == 0:
            if FreeCADGui.ActiveDocument.getObject(i.Name).Visibility == True:
                try: 
                    if i.Shape.Shells <> []: #必須為3D物件
                        if fix == 1: errorDialog('物件:'+str(i.Label)+'\n')
                        if fix == 1: errorDialog(str(shape_list))
                        for j in shape_list:
                            if fix==1: errorDialog('\ni:'+str(i.Label)+'   j:'+str(j)+'  =>  '+str(len(i.Shape.common(j).Faces)))
                            if len(i.Shape.common(j).Faces) >= 1: # 取得各種資訊
                                if fix==1: errorDialog('get FACELIST~')
                                sel_line_up2 += 1
                                commonFace = i.Shape.common(j).Faces # Face 
                                cutobj = i
                                objbaseshape = j
                                shape_sum += 1
                                prf('objName',cutobj.Name)
                                TRA = FreeCADGui.ActiveDocument.getObject(cutobj.Name).Transparency   # 取得透明度
                                scolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).ShapeColor  # 取得形狀顏色
                                lcolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).LineColor  # 取得線顏色
                                pcolar=FreeCADGui.ActiveDocument.getObject(cutobj.Name).PointColor  # 取得點顏色
                                try:
                                    C_GRP = cutobj.GROUP
                                    C_ID = cutobj.ID
                                except:
                                    C_GRP = []
                                    C_ID = []
                                    prf("NO~~~group  id")
                                if cutobj.InList <> []:  #取得所在資料夾位置
                                    groupname = cutobj.InList[0].Name
                                    mygroup = FreeCAD.ActiveDocument.getObject(groupname)
                                name = cutobj.Label #取得名稱
                                prf("Transparency",TRA)
                                prf('scolar',scolar)
                                prf('lcolar',lcolar)
                                prf('pcolar',pcolar)
                                prf('mygroup',mygroup)
                                prf('name',name)# 要被切的物件  Base的面  common面  透明度 顏色 點 線 形狀 資料夾 group id
                                FACELIST.append([i,j,commonFace,TRA,scolar,lcolar,pcolar,mygroup,name,C_GRP,C_ID]) 
                        try: # 在中間的物件
                            if i.Shape.common(BOXSHAPE).Area == i.Shape.Area: #在中間
                                ONMIDOBJ.append(i)
                                prf('Area SAME')
                            else:
                                prf('Area NOT SAME . . . !  ')
                        except:
                            prf('MID FIND ERROR...')
                    elif len(i.Shape.Edges) == 1: # 線
                        cutgroup = []
                        if i.InList <> []:  #取得所在資料夾位置
                            groupname = i.InList[0].Name
                            cutgroup = FreeCAD.ActiveDocument.getObject(groupname)
                        L_v1 = i.Shape.Vertex1.Point
                        L_v2 = i.Shape.Vertex2.Point
                        if shell_shape.BoundBox.isInside(L_v1):
                            cutline.append([i,L_v1,L_v2,cutgroup])
                        else:
                            cutline.append([i,L_v2,L_v1,cutgroup])
                except: prf('\nNo Shape.')
                # 兩個面touch....
                prf('FACELIST',FACELIST)
                prf('sel_line_up2',sel_line_up2)
                if sel_line_up2 == 2:
                    prf('FASELIST[-1]',FACELIST[-1])
                    prf('FASELIST[-2]',FACELIST[-2])
                    FACELIST[-1].append(2)
                    FACELIST[-1].append(1)
                    FACELIST[-2].append(2)
                    FACELIST[-2].append(2)
                elif sel_line_up2 == 1:
                    FACELIST[-1].append(1)
                elif sel_line_up2 > 2:
                    FACELIST[-1].append(3)
    prf('FACELIST',FACELIST)
    if shape_sum == 0:
        errorDialog("沒有找到物件!")
        bar_close()
        return(0,0)
    #收尋GROUP
    ###
    C_CM=[]
    C_NM=[]
    CMOBJLIST = []
    NMOBJLIST = []
    NUM=1
    NUM1=len(FACELIST)
    bar_showup()
    for i in FACELIST: # 要被切的物件  Base的面  common面  透明度 (顏色)點 線 形狀 資料夾 group id 2or1 2or1
        if i[-1] == 2: # 一個物件切到兩個面
            prf("物件切到兩面 忽略~")
            bar_setvalue(100)
        elif i[-1] > 2:
            prf('物件切超過兩個面 忽略~')
            bar_setvalue(100)
        else:
            bar_setvalue(NUM*100/NUM1)
            NUM+=1
            objbase = mkObj(i[1])
            objnor = commonFace[0].normalAt(0,0) # obj nor 
            #長出薄片
            EXT = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrude")
            EXT.Base = objbase
            EXT.Dir = objnor*0.0001*-1
            EXT.Solid = (True)
            FreeCAD.ActiveDocument.recompute()
            #物件與薄片切割
            mycut = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut")
            mycut.Base = i[0]
            mycut.Tool = EXT
            FreeCAD.ActiveDocument.recompute()
            DOW = Draft.downgrade([mycut],delete=True)
            prf('DOW',DOW   ) # 切出來的東西...
            FreeCAD.ActiveDocument.recompute()
            T_CM=[]
            T_NM=[]
            for ii in DOW[0]:
                prf('common der Face:',len(BOXSHAPE.common(ii.Shape).Solids))
                if len(BOXSHAPE.common(ii.Shape).Solids) ==1:
                    T_CM.append(ii) # MOVE
                    prf("MOVE")
                else:
                    T_NM.append(ii)# NO MOVE
                    prf("NO MOVE")
            C_CM.append(T_CM)
            C_NM.append(T_NM)
            for ii in DOW[0]:
                FreeCADGui.ActiveDocument.getObject(ii.Name).Transparency = i[3]   # 透明度
                FreeCADGui.ActiveDocument.getObject(ii.Name).ShapeColor = i[4]  # 形狀顏色
                FreeCADGui.ActiveDocument.getObject(ii.Name).LineColor = i[5]      # 線顏色
                FreeCADGui.ActiveDocument.getObject(ii.Name).PointColor = i[6]   # 點顏色
            prf('del objbase',objbase.Name)
            FreeCAD.ActiveDocument.removeObject(objbase.Name)
            #~ prf("i[0].Name",i[0].Name)
            DELII.append(i[0].Name) # 找到的需要拉昇物件
            prf("EXT.Name",EXT.Name)
            FreeCAD.ActiveDocument.removeObject(EXT.Name) # 薄片實體
            prf("C_CM",C_CM)
            prf("C_NM",C_NM)
    bar_close()
    return(C_CM,C_NM)
global fix
fix = 0
'''
from GsCad.fc_cmd import s3d
reload(s3d)
#~ s3d.showup()
p1 = FreeCAD.Vector(-15.0,5.0,0.0)
p2 = FreeCAD.Vector(15.0,5.0,0.0)
p3 = FreeCAD.Vector(15.0,15.0,0.0)
p4 = FreeCAD.Vector(-15.0,15.0,0.0)
a,b=s3d.cutobj(p1,p2,p3,p4)
s3d.ssobj(a,b,FreeCAD.Vector(0,5,0))

'''

def ssobj(CO_CM,CO_NM,MOV):
    global name,lcolor,pcolor,scolor,mygroup,commonFace,FACELIST,DELII,oklist
    global fix , cutline
    # 線段移動
    if cutline:
        for i in cutline:
            cutline1 = Draft.makeLine(i[1]+MOV,i[2])
            FreeCAD.ActiveDocument.removeObject(i[0].Name)
            if i[3]: i[3].addObject(cutline1)
    # 增加的面積
    oklist = []
    prf("FACELIST",FACELIST)
    num=0
    DELLIST=[]
    KED = 0
    LENN = MOV.Length
    LEN = MOV.Length+0.0015
    objnor = MOV.normalize() # obj nor 
    MMOV = objnor*LENN
    bar_showup()
    NUM=1
    NUM1=len(FACELIST)
    for ii in FACELIST: # N個物件  [  [obj,obj,[face,face,face],tra,pc,lc,sc,group,name,grp,id] , [...] , [...] , [...] ,1or2 ]
        if fix == 1: errorDialog('FACELIST 迴圈')
        ii[0].Label = 'temp'
        bar_setvalue(NUM*100/NUM1)
        NUM+=1
        CLOUD9=[] # 需要融合的物件
        TPA=[]
        sel_2_face = 0
        if ii[-2] == 2 :# 有兩個面跟物件碰到........
            if ii[-1] == 2: # 第二個面開始工作時...
                sel_2_face = 1
        for i in ii[2]:# commonface (基準面)
            if fix == 1: errorDialog("Extrude")
            TPA.append(mkObj(i))
            AEXT = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrude") # Face長出實體
            AEXT.Base = TPA[-1]
            AEXT.Dir = objnor*(LEN)
            AEXT.Solid = (True)
            FreeCAD.ActiveDocument.recompute()
            for j in CO_NM[num]: # 判斷切 或是 融合
                if AEXT.Shape.common(j.Shape).Area > 0.1:
                    KED = 1
            if KED == 1:    #  縮
                AEXT.Dir = objnor*(LEN-0.0011)
            else: #   拉
                AEXT.Dir = objnor*(LEN)
            FreeCAD.ActiveDocument.recompute()
            CLOUD9.append(AEXT)   #  把長出的實體丟到C9
            Draft.move(AEXT,objnor*-0.0005,copy=False)#拉昇obj 微移動 避免小縫隙
            FreeCAD.ActiveDocument.recompute()
        # CM物件移動
        Draft.move(CO_CM[num],MMOV,copy=False)
        prf('MOV',MOV)
        if KED == 1:    #  縮
            prf("縮")
            if fix == 1: errorDialog('縮')
            ############################ CLOUD9 = 切面長出的實體
            if len(CLOUD9) > 1:  #  長出的實體
                MuCut = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","myEXXXX")
                MuCut.Shapes = CLOUD9
                FreeCAD.ActiveDocument.recompute()
            else:
                MuCut = CLOUD9[0]
                MuCut.Label = 'myEXXXX'
            ###############################
            DELLIST.append(MuCut.Name)
            if len(CO_NM[num]) > 1: # CUT BASE
                SECut = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","CUTBASE")
                SECut.Shapes = CO_NM[num]
                FreeCAD.ActiveDocument.recompute()
            else:
                SECut = CO_NM[num][0]
                SECut.Label = 'CUTBASE'
            if fix == 1: errorDialog('CUT')
            DELLIST.append(SECut.Name)
            C9Cut = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut") # 切!
            C9Cut.Base = SECut # 不移動的主體
            C9Cut.Tool = MuCut # 長出的實體
            DELLIST.append(C9Cut.Name)
            #~ Draft.move(C9Cut,objnor*-0.0012,copy=False) # ?
            FreeCAD.ActiveDocument.recompute()
            COO = [] # 融合物件
            COO.append(C9Cut)
            for k in CO_CM[num]:
                COO.append(k)
            if fix == 1: errorDialog('Fusion')
            Mu = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","Fusion")
            Mu.Shapes = COO
            FreeCAD.ActiveDocument.recompute()
            Mui = mkObj(Mu.Shape)
            if ii[7]: mygroup.addObject(Mui)  #群組
            FreeCADGui.ActiveDocument.getObject(Mui.Name).Transparency = ii[3]   # 透明度
            FreeCADGui.ActiveDocument.getObject(Mui.Name).ShapeColor = ii[4]  # 形狀顏色
            FreeCADGui.ActiveDocument.getObject(Mui.Name).LineColor = ii[5]      # 線顏色
            FreeCADGui.ActiveDocument.getObject(Mui.Name).PointColor = ii[6]   # 點顏色
            oklist.append(Mui)
            DELLIST.append(Mu.Name) # 融合物件
            for iii in CO_NM[num]:
                CLOUD9.append(iii)
            for iii in CO_CM[num]:
                CLOUD9.append(iii)
            for ww in CLOUD9:
                DELLIST.append(ww.Name)
            for ww in TPA:
                DELLIST.append(ww.Name) # 薄片的面
            num+=1
            Mui.Label = ii[8]    #名稱
        else:    #  拉
            prf("拉")
            for i in CO_NM[num]:
                CLOUD9.append(i)
            for i in CO_CM[num]:
                CLOUD9.append(i)
            if fix == 1:
                errorDialog('拉..  Fusion')
                c999 = []
                for k in CLOUD9:
                    c999.append(k.Label)
                errorDialog('CLOUD9.Label'+str(c999))
                return()
            Mu = FreeCAD.ActiveDocument.addObject("Part::MultiFuse","Fusion")
            Mu.Shapes = CLOUD9
            FreeCAD.ActiveDocument.recompute()
            Mui = mkObj(Mu.Shape)
            if ii[7]: mygroup.addObject(Mui)  # 群組
            FreeCADGui.ActiveDocument.getObject(Mui.Name).Transparency = ii[3]   # 透明度
            FreeCADGui.ActiveDocument.getObject(Mui.Name).ShapeColor = ii[4]  # 形狀顏色
            FreeCADGui.ActiveDocument.getObject(Mui.Name).LineColor = ii[5]      # 線顏色
            FreeCADGui.ActiveDocument.getObject(Mui.Name).PointColor = ii[6]   # 點顏色
            oklist.append(Mui)
            DELLIST.append(Mu.Name) # 融合物件
            for ww in TPA:
                DELLIST.append(ww.Name) # 薄片的面
            for ww in CLOUD9:
                DELLIST.append(ww.Name) # 薄片 物件A 物件B
            num+=1
            Mui.Label = ii[8]  #名稱
    bar_close()
    prf("DELLIST",DELLIST)
    for i in DELLIST:
        try:
            FreeCAD.ActiveDocument.removeObject(i)
        except:
            prf("DEL 重複!")
    prf("DELII",DELII)
    for i in DELII:
        try: FreeCAD.ActiveDocument.removeObject(i)
        except: prf("DELII no",i)
def showup():
    global reobsel , StaSel
    reobsel = Ui_reobsel()
    FreeCADGui.Control.showDialog(reobsel)
    #~ StaSel = StandSelObserver()
    #~ FreeCADGui.Selection.addObserver(StaSel)

def isPtOnEdge(pt,edge) : # find is point on edge
    v = Part.Vertex(pt)
    d = v.distToShape(edge)
    if d:
        if d[0] < 0.01:
            return True
    return False

def mkObj(shape):  # make obj
    obj = FreeCAD.ActiveDocument.addObject("Part::Feature",'Temp')
    obj.Shape = shape
    FreeCAD.ActiveDocument.recompute()
    return(obj)

def errorDialog(msg): # message
    unicode_str =  unicode(msg,'utf-8')
    diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error MessageBox', unicode_str)
    diag.setWindowModality(QtCore.Qt.ApplicationModal)
    diag.exec_()

def prf(m,p=0):
    if p==0: FreeCAD.Console.PrintMessage('\n'+str(m))
    else: FreeCAD.Console.PrintMessage('\n'+str(m)+':'+str(p))


1. import and showup()
d1.PNG
d1.PNG (109.11 KiB) Viewed 9380 times
2.select what you want to stretch.
If you select nothing, it will select all objects by default.(If there are many things, it cost you much time)
d2.PNG
d2.PNG (111.91 KiB) Viewed 9380 times
3.Click'Enter'.

4.Determine your scope which you want to stretch.
d3.PNG
d3.PNG (100.77 KiB) Viewed 9380 times
5.Starting stretch. Decide if you want to move away from.
d4.PNG
d4.PNG (118.95 KiB) Viewed 9380 times
6.Fanily, click 'OK' to finish it.
d5.PNG
d5.PNG (119.29 KiB) Viewed 9380 times
Last edited by eason on Thu Jun 02, 2016 7:42 am, edited 1 time in total.
eason
Posts: 111
Joined: Thu Apr 09, 2015 2:40 am
Location: Taiwan

Re: Stretch in 3D

Postby eason » Thu Jun 02, 2016 7:24 am

d6.PNG
d6.PNG (133.58 KiB) Viewed 9380 times
d7.PNG
d7.PNG (98.57 KiB) Viewed 9380 times
Cuyabeno
Posts: 1
Joined: Sat Sep 24, 2016 4:16 pm

Re: Stretch in 3D

Postby Cuyabeno » Sun Oct 30, 2016 6:24 pm

Hello eason,

I am interested in your tool and install this macro, but I get on Ubuntu the message when I start it:
from GsCad.fc_cmd import view
<type 'exceptions.ImportError'>: No module named GsCad.fc_cmd

Can you help me where I can found the module GsCAD.fc_cmd?
User avatar
bernd
Posts: 7095
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Stretch in 3D

Postby bernd » Wed Nov 16, 2016 7:56 am

very cool tool !
chrisb
Posts: 14103
Joined: Tue Mar 17, 2015 9:14 am

Re: Stretch in 3D

Postby chrisb » Wed Nov 16, 2016 7:11 pm

Cuyabeno wrote:Hello eason,

I am interested in your tool and install this macro, but I get on Ubuntu the message when I start it:
from GsCad.fc_cmd import view
<type 'exceptions.ImportError'>: No module named GsCad.fc_cmd

Can you help me where I can found the module GsCAD.fc_cmd?
I have the same problem, but bernd seems to have a running version, since I guess that is comment
bernd wrote:very cool tool !
was not an answer to the GsCad.fc_cmd-problem ;) .
@bernd: could you please look in your python search-path, if some 3rd party workbench or some other macro provides this file.

(same on freecad-daily, and MacOS 0.16.6707)
OS: Ubuntu 14.04.5 LTS
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6703 (Git)
Build type: None
Branch: releases/FreeCAD-0-16
Hash: 2ce5c8d2e3020d05005ed71f710e09e9aa561f40
Python version: 2.7.6
Qt version: 4.8.6
Coin version: 4.0.0a
OCC version: 6.8.0.oce-0.17
User avatar
bernd
Posts: 7095
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Stretch in 3D

Postby bernd » Thu Nov 17, 2016 6:31 pm

Sorry guys I just saw the pictures. Since the CAD we gone use at work has such a tool, and I have been missing the tool in FreeCAD I was quite excited without even test it. But since you guys have been answered I had to test it. Same here. In line 12 it trys to import a module I have never heard about:

Code: Select all

from GsCad.fc_cmd import view
and I get the same error than you guys.

if I just comment this line nothing happens, no error no task view just nothing.