Stretch in 3D

Show off your FreeCAD projects here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
easyw-fc
Veteran
Posts: 3633
Joined: Thu Jul 09, 2015 9:34 am

Re: Stretch in 3D

Post by easyw-fc »

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?
that is related to pythonocc
viewtopic.php?f=22&t=14730&p=118077#p118247
looo wrote:I assumed that this "C:/GS3D/Mod/GsCad/occ" is your python-occ module but actually it's not?
If you have placed the OCC-python-module in "C:/FreeCAD/Mod" FreeCAD will add "C:/FreeCAD/Mod/OCC" to the sys.path. This is actually a bad behaviour of FreeCAD as you would have to write "import __init__" to load the OCC module. So you could add a directory "C:/FreeCAD/Mod/py_modules" and place the OCC-python-module there. So the path to the module should look like "C:/FreeCAD/Mod/py_modules/OCC".

The better solution would be to place the module somewhere in the std. python-path.
chrisb
Veteran
Posts: 54150
Joined: Tue Mar 17, 2015 9:14 am

Re: Stretch in 3D

Post by chrisb »

It is not only a question of search paths, this file "GsCad.fc_cmd" exists nowhere on my system. I searched with google - nothing. Because the other topic was about pythonocc I searched there for the file - nothing. I searched the source code of pythonocc in the hope the file would be created - nothing. I am at a loss.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Stretch in 3D

Post by bernd »

chrisb wrote:It is not only a question of search paths, this file "GsCad.fc_cmd" exists nowhere on my system. I searched with google - nothing. Because the other topic was about pythonocc I searched there for the file - nothing. I searched the source code of pythonocc in the hope the file would be created - nothing. I am at a loss.
I did nearly the same search as you, same result: +1

May be it is his own module ?!
chrisb
Veteran
Posts: 54150
Joined: Tue Mar 17, 2015 9:14 am

Re: Stretch in 3D

Post by chrisb »

Let's quote eason, perhaps he is listening:
@eason: you use an unknown file
eason wrote:

Code: Select all

...
from GsCad.fc_cmd import view
...
could you please tell us where to find this file or provide it here if it is yours?
Thanks
Chris
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
eason
Posts: 120
Joined: Thu Apr 09, 2015 2:40 am
Location: Taiwan

Re: Stretch in 3D

Post by eason »

I'm sorry I forgot that!

It is view.py

Code: Select all

# -*- coding: utf-8 -*-
from pivy import coin
import FreeCADGui
global sg,ma,coords,lines,no
def 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 close():
    global sg,coords,lines,no,ma
    
    no.removeChild(coords)
    no.removeChild(lines)
    no.removeChild(ma)
    #sg.removeChild(coords)

def set(pts,num):
    global sg,ma,coords,lines,no
    coords.point.setValues(pts)
    lines.coordIndex.setValues(0,len(num),num)

def 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)
chrisb
Veteran
Posts: 54150
Joined: Tue Mar 17, 2015 9:14 am

Re: Stretch in 3D

Post by chrisb »

eason wrote:I'm sorry I forgot that!

It is view.py
Still not usable. I saved the last code you posted as view.py, GsCad.fc_cmd, GsCad.fc_cmd.py, all to no avail. I get the same error message as before. If you want anyone to use your stretcher please make a complete package and a complete instruction of how to install/use it.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
User avatar
easyw-fc
Veteran
Posts: 3633
Joined: Thu Jul 09, 2015 9:34 am

Re: Stretch in 3D

Post by easyw-fc »

chrisb wrote:
eason wrote:I'm sorry I forgot that!

It is view.py
Still not usable. I saved the last code you posted as view.py, GsCad.fc_cmd, GsCad.fc_cmd.py, all to no avail. I get the same error message as before. If you want anyone to use your stretcher please make a complete package and a complete instruction of how to install/use it.
I saved it as view.py and modified the line

Code: Select all

from GsCad.fc_cmd import view
to

Code: Select all

import view
then no errors, but still no GUI showing...
Maurice
chrisb
Veteran
Posts: 54150
Joined: Tue Mar 17, 2015 9:14 am

Re: Stretch in 3D

Post by chrisb »

Thank you, that is a step further.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
eason
Posts: 120
Joined: Thu Apr 09, 2015 2:40 am
Location: Taiwan

Re: Stretch in 3D

Post by eason »

try this.

Code: Select all

import stretch  # which you save name
stretch.showup() # run Gui
User avatar
easyw-fc
Veteran
Posts: 3633
Joined: Thu Jul 09, 2015 9:34 am

Re: Stretch in 3D

Post by easyw-fc »

eason wrote:try this.

Code: Select all

import stretch  # which you save name
stretch.showup() # run Gui
ok, I found a way to get the GUI:
1) create a file named s3d.py
2) you need 3 files
- s3d.py
- stretch3D.py
- stretchView.py
3) open a FC file with some 3d objs
4) run s3d.py in FC 0.16 stable (FC 0.17 has some changes that will not let the macro work atm)

still I have to learn howto use it ;)
I also get some errors and difficult to translate messages (I will do with G)

EDIT:
I got it 'sort of' working :D

here the files in a single zipped
s3d.zip
(9.63 KiB) Downloaded 128 times
stretch3D-view.png
stretch3D-view.png (199.94 KiB) Viewed 4991 times
EDIT #2:

s3d.py

Code: Select all

import stretch3D

global FACELIST , linkobj
global LCD_CM,LCD_NM,SSCM,movt,ONMIDOBJ,MD,change_sel_mode

stretch3D.showup() # run Gui
stretchView.py

Code: Select all

# -*- coding: utf-8 -*-
from pivy import coin
import FreeCADGui
global sg,ma,coords,lines,no
global FACELIST , linkobj
global LCD_CM,LCD_NM,SSCM,movt,ONMIDOBJ,MD,change_sel_mode

def 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 close():
    global sg,coords,lines,no,ma
   
    no.removeChild(coords)
    no.removeChild(lines)
    no.removeChild(ma)
    #sg.removeChild(coords)

def set(pts,num):
    global sg,ma,coords,lines,no
    coords.point.setValues(pts)
    lines.coordIndex.setValues(0,len(num),num)

def 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)
stretch3D.py

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
import stretchView
from pivy import coin
global FACELIST , linkobj
global MD
linkobj = []
FACELIST = []
MD = FreeCAD.Vector(0,0,0)
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

print "starting..."

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,MD,linkobj,change_sel_mode,change_sel_mode,grid_mode
        change_sel_mode = 1 # Select the object mode 選取物件模式
        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: # The selected object is executed 選取物件完才執行
            self.point = FreeCADGui.Snapper.snap(info["Position"],lastpoint,info["CtrlDown"],info["ShiftDown"],True)  #鎖點
        if info["Type"] == "SoKeyboardEvent":   #  Keyboard press event 鍵盤按下事件
            if info["State"] == 'UP':
                if info["Key"] == 'RETURN' or info["Key"] == 'PAD_ENTER':  #  Press 按下 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':  #  按下 Press ESC關掉所有東西 Turn off everything
                self.reob()
        elif info["Type"] == "SoLocation2Event" : #  滑鼠移動事件 Mouse move event  move
            if len(self.stack) == 1:  #框框示意圖 # Frame diagram
                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: #拉昇示意圖 Pull up the schematic
                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":#  滑鼠點擊事件 Mouse click event 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))


# showing the GUI    
bar_showup()
Last edited by easyw-fc on Tue Dec 06, 2016 1:57 pm, edited 1 time in total.
Post Reply