Macro FCWire To Volume/pl

Other languages:

Macro FCWire To Volume

Description
Create a Boolean operation with the selected wires. Push the 2d button to create the Boolean operation on to 2D wire.

Macro version: 0.03
Last modified: 2020/06/02
FreeCAD version: 0.19 and more
Download: ToolBar Icon
Author: Mario52
Author
Mario52
Download
ToolBar Icon
Links
Macro Version
0.03
Date last modified
2020/06/02
FreeCAD Version(s)
0.19 and more
Default shortcut
None
See also
None

Description

This macro creates a Boolean object with the selected Draft object.

Usage

Thickness Solide

Choice

Boolean

Intersection : Boolean operation

Substraction : Boolean operation

Union : Boolean operation

Xor : Boolean operation

Axis

X Axis : Axis X

Y Axis : Axis Y

Z Axis : Axis Z (default)

Direction : (Not functional Later)

Option

Single object : If the checkBox is checked the object is on single object, if not the object created conserve the hierarchy of the construction the object

Hidden : The original object are hidden

Color : If it checked the object resultant is coloured in red

Command

Script

Copy the macro in your macro folder.

The icon for the tool bar


Macro_FCWire_To_Volume.FCMacro

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
#
"""
***************************************************************************
*   Copyright (c) <mario52> 2016 2017 2018 2019 2020 2021 2022 2023 2024  *
*   2025                                                                  *
*   This file is a supplement to the FreeCAD CAx development system.      *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Lesser General Public License (LGPL)    *
*   as published by the Free Software Foundation; either version 2 of     *
*   the License, or (at your option) any later version.                   *
*   for detail see the LICENCE text file.                                 *
**                                                                       **
*   Use at your own risk. The author assumes no liability for data loss.  *
*              It is advised to backup your data frequently.              *
*             If you do not trust the software do not use it.             *
**                                                                       **
*   This software is distributed in the hope that it will be useful,      *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU Library General Public License for more details.                  *
*                                                                         *
*   You should have received a copy of the GNU Library General Public     *
*   License along with this macro; if not, write to the Free Software     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
*   USA                                                                   *
***************************************************************************
*           WARNING! All changes in this file will be lost and            *  
*                  may cause malfunction of the program                   *
***************************************************************************
"""
#Macro_FCWire_To_Volume 10/10/2016_01, 2020/04/08_02, 2020/04/10_2b, 2020/04/10_2c, 02/06/2025_03
#
#OS: Windows 10 (10.0)                           #OS: Windows 10 build 19045
#Word size of OS: 64-bit                         #Architecture: x86_64
#Word size of FreeCAD: 64-bit                    #Version: 1.1.0dev.41905 (Git)
#Version: 0.19.20311 (Git)                       #Build date: 2025/05/30 18:02:58
#Build type: Release                             #Build type: Release
#Branch: master                                  #Branch: main
#Hash: 915e551bbb7e3614bc804f1ae1f65027b5432b9f  #Hash: 239a05b242b9162fd7a5ab13dcfa86b097c5ad55
#Python version: 3.6.8                           #Python 3.11.12, Qt 6.8.3, Coin 4.0.3, Vtk 9.3.1, boost 1_86, Eigen3 3.4.0, PySide 6.8.3
#Qt version: 5.12.1                              #shiboken 6.8.3, xerces-c 3.2.5, IfcOpenShell 0.8.2, OCC 7.8.1
#Coin version: 4.0.0a                            #Locale: French/Mars (fr_MA)
#OCC version: 7.3.0                              #Navigation Style/Orbit Style/Rotation Mode: CAD/Trackball/Drag at cursor
#                                                #Stylesheet/Theme/QtStyle: unset/FreeCAD Classic/fusion
#                                                #Logical DPI/Physical DPI/Pixel Ratio: 96/99.0075/1
#
__title__   = u"Macro_FCWire_To_Volume"
__author__  = u"Mario52"
__url__     = u"https://wiki.freecadweb.org/Macro_FCWire_To_Volume"
__version__ = u"00.03"
__date__    = u"2025/06/02"    #YYYY/MM/DD

#if int(FreeCAD.Version()[1]) < 18:      # Version de FreeCAD
#    FreeCAD.Console.PrintMessage(u"This version " + __title__ + " rmu  work with the FreeCAD 0.18 or higher. " + "\n\n")

import PySide
try:
    from PySide import QtWidgets
    from PySide.QtWidgets import *
except Exception:
    None
from PySide import QtGui , QtCore
from PySide.QtGui import *
from PySide.QtCore import *
#
try:
    import webbrowser
except Exception:
    None

import Draft, Part, PartGui, FreeCADGui, FreeCAD
from FreeCAD import Base
import math
from math import sqrt, pi, sin, cos, asin

Gui = FreeCADGui
App = FreeCAD

global create2D ; create2D = 0
global ui       ; ui       = ""
global doc

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_MainWindow(object):

    def __init__(self ):
        self.window = MainWindow
        #self.path   = FreeCAD.ConfigGet(u"AppHomePath")
        self.path   = FreeCAD.ConfigGet(u"UserAppData")
        self.path   = self.path.replace(u"\\","/")

        self.thicknessValue  = 0.0
        self.thicknessX      = 0.0     # extrusion
        self.thicknessY      = 0.0     # extrusion
        self.thicknessZ      = 0.0     # extrusion
        self.thicknessD      = 0.0     # extrusion

    def setupUi(self, MainWindow):
        self.window = MainWindow
        MainWindow.setObjectName(_fromUtf8(u"__title__"))
        MainWindow.resize(300, 300)
#        MainWindow.setMinimumSize(QtCore.QSize(300, 200))
#        MainWindow.setMaximumSize(QtCore.QSize(300, 200))
        self.centralwidget = QWidget(MainWindow)

        self.groupBox0 = QGroupBox()
        self.groupBox_01 = QGroupBox()

        self.doubleSpinBox = QDoubleSpinBox()
        self.doubleSpinBox.setMinimum(0)
        self.doubleSpinBox.setMaximum(999999.999999)
        self.doubleSpinBox.setDecimals(3)
        self.doubleSpinBox.setValue(0.0)
        self.doubleSpinBox.setAlignment(QtCore.Qt.AlignCenter)
        self.doubleSpinBox.setSuffix(u" mm")
        self.doubleSpinBox.valueChanged.connect(self.on_doubleSpinBox) ###
        ####
        self.groupBox_02 = QGroupBox()

        self.GroupBox_Bool = QGroupBox()
        self.RB_Intersection = QRadioButton()
        self.RB_Intersection.setIcon(QtGui.QIcon.fromTheme(u"bool",QtGui.QIcon(u":/icons/Part_Common.svg")))
        self.RB_Intersection.setChecked(True)
        self.RB_Cut = QRadioButton()
        self.RB_Cut.setIcon(QtGui.QIcon.fromTheme(u"bool",QtGui.QIcon(u":/icons/Part_Cut.svg")))
        self.RB_Union = QRadioButton()
        self.RB_Union.setIcon(QtGui.QIcon.fromTheme(u"bool",QtGui.QIcon(u":/icons/Part_Fuse.svg")))
        self.RB_Xor = QRadioButton()
        self.RB_Xor.setIcon(QtGui.QIcon.fromTheme(u"bool",QtGui.QIcon(u":/icons/Part_XOR.svg")))
        ####
        self.groupBox_Axis = QGroupBox()
        self.RB_Axis_X = QRadioButton()
        self.RB_Axis_X.setIcon(QtGui.QIcon.fromTheme(u"axis",QtGui.QIcon(u":/icons/Std_CoordinateSystem.svg")))
        self.RB_Axis_Y = QRadioButton()
        self.RB_Axis_Y.setIcon(QtGui.QIcon.fromTheme(u"axis",QtGui.QIcon(u":/icons/Std_CoordinateSystem.svg")))
        self.RB_Axis_Z = QRadioButton()
        self.RB_Axis_Z.setChecked(True)
        self.RB_Axis_Z.setIcon(QtGui.QIcon.fromTheme(u"axis",QtGui.QIcon(u":/icons/Std_CoordinateSystem.svg")))
        self.RB_Axis_D = QRadioButton()
        self.RB_Axis_D.setEnabled(False)
        self.RB_Axis_D.setIcon(QtGui.QIcon.fromTheme(u"axis",QtGui.QIcon(u":/icons/Part_Line_Parametric.svg")))#Std_CoordinateSystem
        ####
        self.groupBox_03 = QGroupBox()
        self.checkBox_01 = QCheckBox()
        self.checkBox_01.setChecked(True)             #  # False
        self.checkBox_01.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u":/icons/Tree_Part.svg")))
        self.checkBox_01.clicked.connect(self.on_checkBox_01) ###

        self.CB_Create_2D_Visible = QCheckBox()
        self.CB_Create_2D_Visible.setChecked(True)    #    # False
        self.CB_Create_2D_Visible.clicked.connect(self.on_CB_Create_2D_Visible) ###
#        self.CB_Create_2D_Visible.setIcon(QtGui.QIcon.fromTheme(u"draft",QtGui.QIcon(u":/icons/dagViewVisible.svg")))#

        self.CB_Colorer = QCheckBox()
        self.CB_Colorer.setChecked(False)             # True   # 
        self.CB_Colorer.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u":/icons/colors.svg")))
        ####
        self.groupBox_04 = QGroupBox()
        self.PB_Create_2D = QPushButton()
        self.PB_Create_2D.clicked.connect(self.on_PB_Create_2D) ###
        self.PB_Create_2D.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_DialogOkButton))) #
        self.PB_Create = QPushButton()
        self.PB_Create.clicked.connect(self.on_PB_Create) ###
        self.PB_Create.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_DialogOkButton))) #
        self.PB_Help = QPushButton()
        self.PB_Help.clicked.connect(self.on_PB_Help) ###
        self.PB_Help.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion))) #
        self.PB_Quit = QPushButton()
        self.PB_Quit.clicked.connect(self.on_PB_Quit) ###
        self.PB_Quit.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_DialogCloseButton))) #

        ####gridLayout####
        self.gridLayout0 = QGridLayout(self.centralwidget)
        self.gridLayout0.setContentsMargins(10, 10, 10, 10)
        self.gridLayout0.addWidget(self.groupBox0, 0, 0, 1, 1)
        ####
        self.gridLayout = QGridLayout(self.groupBox0)
        self.gridLayout.setContentsMargins(10, 10, 10, 10)
        ####
        self.gridLayout_02 = QGridLayout(self.groupBox_01)
        self.gridLayout_02.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_02.addWidget(self.doubleSpinBox, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.groupBox_01, 0, 0, 1, 2)
        ####
        self.gridLayout_03 = QGridLayout(self.groupBox_02)
        self.gridLayout_03.setContentsMargins(10, 10, 10, 10)
        ####
        self.gridLayout_04 = QGridLayout(self.GroupBox_Bool)
        self.gridLayout_04.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_04.addWidget(self.RB_Intersection, 0, 0, 1, 1)
        self.gridLayout_04.addWidget(self.RB_Cut, 1, 0, 1, 1)
        self.gridLayout_04.addWidget(self.RB_Union, 2, 0, 1, 1)
        self.gridLayout_04.addWidget(self.RB_Xor, 3, 0, 1, 1)
        self.gridLayout_03.addWidget(self.GroupBox_Bool, 0, 0, 1, 1)
        ####
        self.gridLayout_05 = QGridLayout(self.groupBox_Axis)
        self.gridLayout_05.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_05.addWidget(self.RB_Axis_X, 0, 0, 1, 1)
        self.gridLayout_05.addWidget(self.RB_Axis_Y, 1, 0, 1, 1)
        self.gridLayout_05.addWidget(self.RB_Axis_Z, 2, 0, 1, 1)
        self.gridLayout_05.addWidget(self.RB_Axis_D, 3, 0, 1, 1)
        self.gridLayout_03.addWidget(self.groupBox_Axis, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.groupBox_02, 1, 0, 1, 2)
        ####
        self.gridLayout_06 = QGridLayout(self.groupBox_03)
        self.gridLayout_06.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_06.addWidget(self.checkBox_01, 0, 0, 1, 1)
        self.gridLayout_06.addWidget(self.CB_Create_2D_Visible, 0, 1, 1, 1)
        self.gridLayout_06.addWidget(self.CB_Colorer, 0, 2, 1, 1)
        self.gridLayout.addWidget(self.groupBox_03, 2, 0, 1, 2)
        ####
        self.gridLayout_07 = QGridLayout(self.groupBox_04)
        self.gridLayout_07.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_07.addWidget(self.PB_Create_2D, 0, 0, 1, 1)
        self.gridLayout_07.addWidget(self.PB_Create, 0, 1, 1, 1)
        self.gridLayout_07.addWidget(self.PB_Help, 1, 0, 1, 1)
        self.gridLayout_07.addWidget(self.PB_Quit, 1, 1, 1, 1)
        self.gridLayout.addWidget(self.groupBox_04, 3, 0, 1, 2)
        ####gridLayout####

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(u"FCWire To Volume")#
        MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)        # PySide cette fonction met la fenetre en avant

        self.groupBox0.setTitle(_translate(u"MainWindow", __title__ + " " + "Ver : " + __version__ + " : " + __date__) + " rmu") #
        self.groupBox_01.setTitle(_translate(u"MainWindow", "Thickness Solide"))
        self.groupBox_02.setTitle(_translate(u"MainWindow", "Choice"))

        self.GroupBox_Bool.setTitle(_translate(u"MainWindow", "Boolean"))
        self.RB_Intersection.setText(_translate(u"MainWindow", "Intersection"))
        self.RB_Cut.setText(_translate(u"MainWindow", "Substraction"))
        self.RB_Union.setText(_translate(u"MainWindow", "Union"))
        self.RB_Xor.setText(_translate(u"MainWindow", "Xor"))

        self.groupBox_Axis.setTitle(_translate(u"MainWindow", "Axis"))
        self.RB_Axis_X.setText(_translate(u"MainWindow", "X Axis"))
        self.RB_Axis_X.setToolTip(_translate(u"MainWindow", "Plane YZ extrude direction X"))
        self.RB_Axis_Y.setText(_translate(u"MainWindow", "Y Axis"))
        self.RB_Axis_Y.setToolTip(_translate(u"MainWindow", "Plane XZ extrude direction Y"))
        self.RB_Axis_Z.setText(_translate(u"MainWindow", "Z Axis"))
        self.RB_Axis_Z.setToolTip(_translate(u"MainWindow", "Plane XY extrude direction Z"))
        self.RB_Axis_D.setText(_translate(u"MainWindow", "Direction"))
        self.RB_Axis_D.setToolTip(_translate(u"MainWindow", "Extrude direction (for later)"))

        self.groupBox_03.setTitle(_translate(u"MainWindow", "Option"))
        self.checkBox_01.setText(_translate(u"MainWindow", "Single object"))
        self.checkBox_01.setToolTip(_translate(u"MainWindow", "Check this checkBox"+"\n"+
                                               "for create single object"))
        self.CB_Create_2D_Visible.setText(_translate(u"MainWindow", "Hidden"))
        self.CB_Create_2D_Visible.setToolTip(_translate(u"MainWindow", "The object used are Hidden"))
        self.CB_Colorer.setText(_translate(u"MainWindow", "Color"))
        self.CB_Colorer.setToolTip(_translate(u"MainWindow", "If is checked the result is colored in red"))
        self.groupBox_04.setTitle(_translate(u"MainWindow", "Command"))
        self.PB_Create_2D.setText(_translate(u"MainWindow", "Create 2D"))
        self.PB_Create_2D.setToolTip(_translate(u"MainWindow", "This button Create 2D object (Draft.makeShape2DView)" + "\n" +
                                                u"The projection is make in the Z axis" + "\n" +
                                                u"The selection order is decisive for the desired result (Substraction)"))
        self.PB_Create.setText(_translate(u"MainWindow", "Create 3D"))
        self.PB_Create.setToolTip(_translate(u"MainWindow", "Create the object 3D" + "\n" +
                                             u"The selection order is decisive for the desired result (Substraction)"))
        self.PB_Help.setText(_translate(u"MainWindow", "Help"))
        self.PB_Help.setToolTip(_translate(u"MainWindow", "Display the wiki page in the FreeCAD browser"))
        self.PB_Quit.setText(_translate(u"MainWindow", "Quit"))
        self.PB_Quit.setToolTip(_translate(u"MainWindow", "Quit Wire to volume, Salut"))


    def on_doubleSpinBox(self,value):
        self.thicknessValue = value
        self.doubleSpinBox.setStyleSheet(u"QDoubleSpinBox {QPalette.Base}")
        self.PB_Create_2D.setStyleSheet(u"QPushButton {QPalette.Base}")
        self.PB_Create.setStyleSheet(u"QPushButton {QPalette.Base}")

    def on_checkBox_01(self):
        if self.checkBox_01.isChecked():
            self.checkBox_01.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u":/icons/Tree_Part.svg")))
            self.checkBox_01.setText(u"Single object")
        else:
            self.checkBox_01.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u":/icons/sel-instance.svg")))
            self.checkBox_01.setText(u"Objects")

    def on_CB_Create_2D_Visible(self):
        if self.CB_Create_2D_Visible.isChecked():
#            self.CB_Create_2D_Visible.setIcon(QtGui.QIcon.fromTheme(u"draft",QtGui.QIcon(u":/icons/dagViewVisible.svg")))#
            self.CB_Create_2D_Visible.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u"")))
            self.CB_Create_2D_Visible.setText(u"Hidden")
        else:
            self.CB_Create_2D_Visible.setIcon(QtGui.QIcon.fromTheme(u"part",QtGui.QIcon(u":/icons/dagViewVisible.svg")))
            self.CB_Create_2D_Visible.setText(u"Visible")

    def on_PB_Create_2D(self):
        global create2D
        global ui

        sel = FreeCADGui.Selection.getSelection()
        self.PB_Create_2D.setStyleSheet(u"QPushButton {QPalette.Base}")
        self.PB_Create.setStyleSheet(u"QPushButton {QPalette.Base}")
        if len(sel) < 2:
            create2D = 0
            self.PB_Create_2D.setStyleSheet(u"QPushButton {background-color: white;\n"
                                            u"border:2px solid rgb(239, 41, 41);}")  # bord white and red
        else:
            create2D = 1
            self.thicknessValue = 1.0
            self.doubleSpinBox.setValue(self.thicknessValue)
            self.RB_Axis_Z.setChecked(True)
            ui.on_PB_Create()

    def on_PB_Create(self):
        global create2D
        global doc

        #if self.thicknessValue == 0:
        #    self.thicknessValue = 1.0
        #    self.doubleSpinBox.setValue(self.thicknessValue)

        selectionObjects = FreeCADGui.Selection.getSelection()
        # setStyleSheet(u"QPushButton {background-color: QPalette.Base}") #red
        self.doubleSpinBox.setStyleSheet(u"QDoubleSpinBox {QPalette.Base}")
        self.PB_Create_2D.setStyleSheet(u"QPushButton {QPalette.Base}")
        self.PB_Create.setStyleSheet(u"QPushButton {QPalette.Base}")
        noface = 0
        ####
        if create2D > 0:
            lab00 = selectionObjects[0].Label
            lab01 = selectionObjects[1].Label
            boolChoice = ""
            if self.RB_Intersection.isChecked():
                boolChoice = "Comm"
            elif self.RB_Cut.isChecked():
                boolChoice = "Subs"
            elif self.RB_Union.isChecked():
                boolChoice = "Unio"
            elif self.RB_Xor.isChecked():
                boolChoice = "Diff"

            if self.checkBox_01.isChecked():
                None
            else:
                FCSpring = FreeCAD.ActiveDocument.addObject(u"App::DocumentObjectGroup","Wire2D_" + lab00 + "_" + boolChoice + "_" +lab01)
        ####
        try:
            selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0] # select one element SubObjects
            if str(selectedEdge)[1:5] == "Face":
                noface = 1
        except Exception:
            None

        selectionDuplicate  = []
        del selectionDuplicate[:]
        p  = []
        del p[:]
        
        try:
            ###########
            self.thicknessX = 0.0
            self.thicknessY = 0.0
            self.thicknessZ = 0.0
    #        self.thicknessD = 0.0

            if self.RB_Axis_X.isChecked():
                self.thicknessX = self.thicknessValue
            if self.RB_Axis_Y.isChecked():
                self.thicknessY = self.thicknessValue
            if self.RB_Axis_Z.isChecked():
                self.thicknessZ = self.thicknessValue
#            if self.RB_Axis_D.isChecked():
#                ##https://forum.freecadweb.org/viewtopic.php?p=199228
#                ##Shape2View in Makro
#                #import FreeCAD,Draft
#                #import pivy
#                #from pivy import coin
#                #App = FreeCAD
#                #
#                #cam=Gui.ActiveDocument.ActiveView.getCameraNode()
#                #rotation = cam.orientation.getValue().multVec(coin.SbVec3f(0,0,1)).getValue()
#                #print( rotation)
#                #
#                #sel = FreeCADGui.Selection.getSelection()	# objects selected
#                #Draft.makeShape2DView(sel[0],FreeCAD.Vector(rotation))
#                #
#                #App.ActiveDocument.recompute()
#                #self.thicknessD = self.thicknessValue
            ###########

            if (len(selectionObjects) >= 2) and (noface == 0) and (self.thicknessX + self.thicknessY + self.thicknessZ != 0.0):
                FreeCAD.ActiveDocument.openTransaction(u"Macro_FCWire_To_Volume")    # memorise les actions (avec annuler restore)
                for i in selectionObjects:            # duplicate object
                    Part.show(i.Shape.copy())
                    sD = doc.ActiveObject
                    sD.Label = i.Name
                    selectionDuplicate.append(sD)

                for i in (selectionDuplicate):        # extrude object
                    a = Draft.extrude(i,Base.Vector(self.thicknessX,self.thicknessY,self.thicknessZ))    # axis extrude X Y Z
                    a.Solid = True
                    p.append(a)

                if self.RB_Intersection.isChecked():
                    name = "Common_" + selectionDuplicate[0].Label         ## create Common_
                    tx = doc.addObject(u"Part::MultiCommon",name)
                    tx.Shapes = p
                    doc.recompute()
                    if self.checkBox_01.isChecked():
                        Part.show(tx.Shape)
                        singleO = App.ActiveDocument.ActiveObject
                        singleO.Label = name
                        doc.removeObject(tx.Name)
                        for i in range(len(selectionDuplicate)):
                            doc.removeObject(selectionDuplicate[i].Name)
                            doc.removeObject(p[i].Name)
                    if self.CB_Colorer.isChecked():
                        FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (1.0,0.0,0.0)
                    App.Console.PrintMessage(u"RB_Intersection ")

                elif self.RB_Cut.isChecked():
                    name = str(u"Cut_" + selectionDuplicate[0].Label)       ## create Cut_
                    tx = doc.addObject(u"Part::Cut",name)
                    tx.Base = p[0]
                    tx.Tool = p[1]
                    doc.recompute()
                    if self.checkBox_01.isChecked():
                        Part.show(tx.Shape)
                        singleO = App.ActiveDocument.ActiveObject
                        singleO.Label = name
                        doc.removeObject(tx.Name)
                        for i in range(len(selectionDuplicate)):
                            doc.removeObject(selectionDuplicate[i].Name)
                            doc.removeObject(p[i].Name)
                    if self.CB_Colorer.isChecked():
                        FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (1.0,0.0,0.0)
                    App.Console.PrintMessage(u"RB_Cut ")

                elif self.RB_Union.isChecked():
                    name = str(u"Fusion_" + selectionDuplicate[0].Label)    ## create Fusion_
                    tx = doc.addObject(u"Part::MultiFuse",name)
                    tx.Shapes = p
                    doc.recompute()
                    if self.checkBox_01.isChecked():
                        Part.show(tx.Shape)
                        singleO = App.ActiveDocument.ActiveObject
                        singleO.Label = name
                        doc.removeObject(tx.Name)
                        for i in range(len(selectionDuplicate)):
                            doc.removeObject(selectionDuplicate[i].Name)
                            doc.removeObject(p[i].Name)
                    if self.CB_Colorer.isChecked():
                        FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (1.0,0.0,0.0)
                    App.Console.PrintMessage(u"RB_Union")

                elif self.RB_Xor.isChecked():
                    name = "CommonD_" + selectionDuplicate[0].Label        ##
                    commun = doc.addObject(u"Part::MultiCommon",name)
                    commun.Shapes = p
                    name = str(u"FusionD_" + selectionDuplicate[0].Label)   ##
                    fusion = doc.addObject(u"Part::MultiFuse",name)
                    fusion.Shapes = p
                    name = str(u"Difference_" + selectionDuplicate[0].Label)## create Difference_
                    difference = doc.addObject(u"Part::Cut",name)
                    difference.Base = fusion
                    difference.Tool = commun
                    doc.recompute()
                    if self.checkBox_01.isChecked():
                        Part.show(difference.Shape)
                        singleO = App.ActiveDocument.ActiveObject
                        singleO.Label = name
                        doc.removeObject(commun.Name)
                        doc.removeObject(fusion.Name)
                        doc.removeObject(difference.Name)
                        for i in range(len(selectionDuplicate)):
                            doc.removeObject(selectionDuplicate[i].Name)
                            doc.removeObject(p[i].Name)
                    if self.CB_Colorer.isChecked():
                        FreeCADGui.ActiveDocument.ActiveObject.ShapeColor = (1.0,0.0,0.0)
                    App.Console.PrintMessage(u"RB_Xor ")

                doc.recompute()
                App.Console.PrintMessage(str(self.thicknessX)+" "+str(self.thicknessY)+" "+str(self.thicknessZ) + "\n")
            else:
                if (self.thicknessX + self.thicknessY + self.thicknessZ == 0.0):
                    App.Console.PrintError(u"Thickness = 0" + "\n")
                    self.doubleSpinBox.setStyleSheet(u"QDoubleSpinBox {background-color: white;\n"
                                                     u"border:2px solid rgb(239, 41, 41);}")  # bord white and red
                else:
                    App.Console.PrintError(u"Not for Face" + "\n")

            #### section 2D
            if create2D > 0:
                FreeCAD.ActiveDocument.openTransaction(u"Macro_FCWire_To_Volume")    # memorise les actions (avec annuler restore)
                objSolid = App.ActiveDocument.getObject(FreeCAD.ActiveDocument.ActiveObject.Name)
                objSolid.Label = "objSolid"

                object2D = Draft.makeShape2DView(objSolid)
                object2D.Label = "object2D"
                FreeCAD.ActiveDocument.recompute()

                Gui.Selection.clearSelection()
                Gui.Selection.addSelection(object2D)

                if self.CB_Create_2D_Visible.isChecked():
                    FreeCADGui.ActiveDocument.getObject(objSolid.Name).Visibility = False
                else:
                    FreeCADGui.ActiveDocument.getObject(objSolid.Name).ShapeColor = (1.0,0.0,0.0)
                    FreeCADGui.ActiveDocument.getObject(objSolid.Name).Transparency = 80

                if self.CB_Colorer.isChecked():
                    FreeCADGui.ActiveDocument.getObject(object2D.Name).LineColor = (1.0,0.0,0.0)

                ##### bon ordre pour effacer
                if self.checkBox_01.isChecked():
                    Part.show(object2D.Shape.copy())
                    if self.CB_Colorer.isChecked():
                        FreeCADGui.ActiveDocument.ActiveObject.LineColor = (1.0,0.0,0.0)
                    App.ActiveDocument.ActiveObject.Label = (u"Wire2D_" + lab00 + "_" + boolChoice + "_" +lab01)
                    doc.removeObject(object2D.Name)
                    doc.removeObject(objSolid.Name)
                else:
                    FCSpring.addObject(objSolid)
                    FCSpring.addObject(object2D)

            if self.CB_Create_2D_Visible.isChecked():
                FreeCADGui.ActiveDocument.getObject(selectionObjects[0].Name).Visibility = False
                FreeCADGui.ActiveDocument.getObject(selectionObjects[1].Name).Visibility = False
            #### section 2D

            create2D = 0
            FreeCAD.ActiveDocument.recompute()
        except Exception:
            print( "Wrong selection or operation")
            self.PB_Create.setStyleSheet(u"QPushButton {background-color: white;\n"
                                         u"border:2px solid rgb(239, 41, 41);}")  # bord white and red

    def on_PB_Help(self): # 
        try:
            webbrowser.open(u"https://wiki.freecadweb.org/Macro_FCWire_To_Volume")
            App.Console.PrintMessage(u"https://wiki.freecadweb.org/Macro_FCWire_To_Volume" + "\n")
        except Exception:
            self.on_PB_Help.setStyleSheet(u"QPushButton {border-width: 2px; border-style: solid; border-color: red}") #red
            self.on_PB_Help.setText(u"Not access")

    def on_PB_Quit(self):                        # Quit
        App.Console.PrintMessage(u"Fin FCWire To Volume " + "\n")
        self.window.hide()

    ####

doc = FreeCAD.ActiveDocument
if doc == None:
    doc = FreeCAD.newDocument()

MainWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()

Exemple

Link

The thread in the forum Bunch of issues/questions

Version

ver 03: 02/06/2025 : return to PySide and little modifications

ver 02c: 11/04/2020 : correct typo "Printmessage" to "PrintMessage"

ver 02b: 10/04/2020 : adding icons and help button

ver 02 : 07/04/2020 : convert for PySide2 Qt5 and layout, adding the 2D (contour) wire

ver 01 : 10/10/2016 :