Sezione Dinamica

Forum per le domande e le discussioni in Italiano
Forum rules
regole del forum e le informazioni utili

Importante: PRIMA di chiedere aiuto leggete qui!
cadcam
Posts: 273
Joined: Thu Apr 02, 2020 10:39 am

Re: Sezione Dinamica

Post by cadcam »

Yes, if face if selected when the macro is started
the cut plane is automatically set to the plane and
the move direction parallel.

Might also be nice to have 2 additional options
once the macro has been started

- Set cut direction to plane next plane selected
- Set cut direction to default

Another nice feature would be to able to orientate
view to normal

Does my explanation that make sense?

Regards


ps. Clipping Planes gets part way there but nicer functionality
with the drag bar in the macro also the solid cut plane visually
nicer. I notice the clipping planes update speed is quicker, at least
on my lowly machine. I was going to have a look at the code to
see if it is possible to drag outline over shaded model and then
update cut plane is no movement for 0.xx seconds
domad
Veteran
Posts: 2051
Joined: Mon Jun 22, 2020 12:16 pm

Re: Sezione Dinamica

Post by domad »

Pierpaolo wrote: Fri Apr 01, 2016 8:18 am Salve
Con Freecad c'è la possibilità di fare una sezione in 3d?
Ho visto che nel modulo Arch c'è lo strumento "Piano di sezione", ma se ho capito bene la sezione viene fatta in 2d.
Uso la versione 0.15 Windows7 64bit
Grazie!
Un saluto a tutta la Comunità!
Argomento molto interessante quello della creazione di una sezione, in particolare se questa diventa “dinamicamente modulabile” nella vista 3D.
Poichè FC è un cad parametrico mi sono prefisso di trovare un medoto che mi consetisse, con gli strumenti che già dispone FC, di ottenere lo stesso risultato raggiunto dall’ottima macro proposta in questo contesto.
Vi espongo, quindi, il procedimento che ho sperimentato con successo, per ottenere il sezionamento dinamico (con variazioni parametriche “millesimali”).
I workbench utilizzati sono il “WorkFeatureDev” e il “Part”.
Le immagini che seguono mostrano:

- l’impostazione della struttura;
- la possibilità di variazione parametrica per la movimentazione (nei tre assi e con agolazioni diversificate anche in contemporanea) del “piano di taglio dinamico” (creato con WorkFeatureDev unitamente alla funzione menu parte --> dividi –> slice apart “Trancia” del banco “Part”) e visualizzazione dinamica con risultato in “realtime”
- l’animazione degli effetti ottenuti novimentando il piano lungo l’asse “Y” e poi ruotadolo attorno all’asse “X” fino a riportarlo al punto di partenza.

Alla luce di questa sperimentazione si potrebbe codificare all’interno del banco “WorkFeatureDev” la/le funzione/i che creino tale piano (o piani) di taglio, che attraverso le schede Proprietà --> Dati-Vista possano essere modulati per ottenere variegati sezionamenti, con la possibilità, una volta definiti, di trasferirli sul banco “TechDraw” per la relativa quotatura.
Attachments
struttura_sez_dinamica.png
struttura_sez_dinamica.png (69.59 KiB) Viewed 6284 times
variaz_param_piano.png
variaz_param_piano.png (80.89 KiB) Viewed 6284 times
sezione_dinamica3.gif
sezione_dinamica3.gif (936.88 KiB) Viewed 6284 times
domad
Veteran
Posts: 2051
Joined: Mon Jun 22, 2020 12:16 pm

Re: Sezione Dinamica

Post by domad »

Pierpaolo wrote: Fri Apr 01, 2016 8:18 am Salve
Con Freecad c'è la possibilità di fare una sezione in 3d?
Ho visto che nel modulo Arch c'è lo strumento "Piano di sezione", ma se ho capito bene la sezione viene fatta in 2d.
Uso la versione 0.15 Windows7 64bit
Grazie!
cadcam wrote: Fri Oct 30, 2020 9:58 pm Yes, if face if selected when the macro is started
the cut plane is automatically set to the plane and
the move direction parallel.
.........
mario52 wrote: Fri Oct 30, 2020 9:01 pm salve
potete rinominare .py in .FCMacro sonno tutti e due lo stesso per FreeCAD
(FCMacro e usato per distinguere una macro dedicata per FreeCAD)
ma se fate un import miofile il file "miofile" da importare deve avere l'estensione "miofile.py" sino non funziona perché diventa uno file Python
su la mia segnatura avete qualunque pagine interessante ma non tutte sono aggiornata
more explanation or image example
(select a face and the "cut" is operate by its normal ? )
mario
g.becu wrote: Tue Aug 20, 2019 8:11 pm Hello, I don't understand this thread. But I came here from the Cross Section macro. It doesn't work with Freecad 0.18.3 and 0.19. There is not a window like this. When I execute it nothing happens.
.....
I must confess I'm new to FreeCAD, but I had the same issue and I wasn't able to find any solution googling. I managed to fix it by adding the following line......
renatorivo wrote: Wed Aug 21, 2019 9:36 pm .......
OS: Windows 8.1
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.16131 (Git)
Build type: Release
Branch: releases/FreeCAD-0-18
Hash: 3129ae4296e40ed20e7b3d460b86e6969acbe1c3
Python version: 3.6.6
Qt version: 5.6.2
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Italian/Italy (it_IT)
Buonasera a tutta la Comunità!
…..riprendendo la sperimentazione precedente, ecco una sezione dinamica composta con angolo di 150°, il risultato è alquanto eloquente.
Le immagini che seguono indicano:
- l’impostazione della struttura;
- l’animazione degli effetti ottenuti novimentando il piano lungo l’asse “Y” con vista dall’alto e con vista assonometrica;
- il disegno tecnico in TechDraw che è anche possibile quotare.
Attachments
strut_sez_composta_dinamica.png
strut_sez_composta_dinamica.png (129.82 KiB) Viewed 6259 times
es_sezionam_composto.gif
es_sezionam_composto.gif (1000.34 KiB) Viewed 6259 times
TechDraw_sez_composta_dinamica.png
TechDraw_sez_composta_dinamica.png (122.37 KiB) Viewed 6259 times
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Sezione Dinamica

Post by mario52 »

Buona sera

impeccabile

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
domad
Veteran
Posts: 2051
Joined: Mon Jun 22, 2020 12:16 pm

Re: Sezione Dinamica

Post by domad »

mario52 wrote: Tue Nov 03, 2020 8:27 pm Buona sera
impeccabile
mario
Buonasera a tutta la Comunità!
Ciao mario52
Ecco l’animazione che spiega passo...passo come eseguire sezionamenti dinamici.
In allegato trovate il file utilizzato per l’animazione.
I piani:
- possono essere uniti tra loro, tramite spigoli, come normali oggetti 3D con le funzioni booleane di “Part”;
- possono essere usati per la funzione “slice-apart” di “Part”;

Consiglio di utilizzare il sezionamento su oggetti unici (interi)

Il sunto passo...passo degli step:
1) creare un solido (consiglio unico o intero) o utilizzare quelli di base di Part;
2) individuare un piano per la creazione del piano/muro di sezionamento, sono sufficienti 3 punti/vertici (per 3 punti passa un solo piano!)
3) selezionare i tre vertici e caricare il workbench WorkFeautureDev e cliccare su crea piano per 3 punti;
4) selezionare il piano appena creato e verificarne le dimensioni in maniera che sia più grande del corpo solido e centrarlo rispetto a questo, quindi, spostarlo sul bordo (assicurasi che intersechi il bordo anche su un punto);
5) selezionare (scheda struttura) il solido e poi il piano prima creato conWFD e utilizzare la funzione slice-apart del workbench Part, dovrebbero formarsi due slice, nascondere quello più sfavorevole alla vista;
6) selezionare il piano di taglio dinamico parametrico o muro e spostarsi nella scheda Dati --> Placement estendere le voci parametriche: asse e posizione e modificarli liberamente avendo cura di operare il refresh (su Linux ctrl+R, su Windows F5, oppure clic tasto invio);
7) nel momento in cui si inverte la visualizzazione, selezionare (scheda struttura) lo sclice precedentemete scelto e sulle scheda Dati --> Invert scegliere l'altro valore;
8) ritornare al piano/muro di sezionameto e continuare l'azione di taglio dinamico.

Buona sperimentazione e continuazione di serata a tutti.
Attachments
tutor_sez_dinam-dynam_sect.FCStd
(197.21 KiB) Downloaded 153 times
tutor_sec_dinamic.gif
tutor_sec_dinamic.gif (983.05 KiB) Viewed 6218 times
MaurinoWeb
Posts: 221
Joined: Thu Jun 22, 2017 1:15 pm

Re: Sezione Dinamica

Post by MaurinoWeb »

Interessante e grazie come sempre domad...
Anche un grazie a tutti ovviamente.
Un saluto
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Sezione Dinamica

Post by mario52 »

saluti
domad wrote: Tue Nov 03, 2020 9:49 pm Ecco l’animazione che spiega passo...passo come eseguire sezionamenti dinamici.
In allegato trovate il file utilizzato per l’animazione.
grazie

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
aleph0
Posts: 43
Joined: Fri Jan 29, 2016 10:04 am
Location: Cambridge, England
Contact:

cross-section macro

Post by aleph0 »

I see the macro has been modified quite a lot since I first posted it. Current discussion seems to be in this Forum, so I'm posting here: I hope enough people understand English as I don't speak Italian.

I have found that the macro doesn't work too well with complex scenes so I have made some changes to my version. One is to make the resolution of the cross-section slider 1000 instead of 100. The slider can be moved in steps of 1 using the keyboard arrow keys and is steps of 10 using the Page Up and page Down keys. Another is to force the menu to disappear while the macro is getting started and display a wait cursor while it's busy. A more logically complex change (but with a big interactivity improvement) is to prevent a whole lot of slider updates from being stacked while the macro is busy.

I don't want to overwrite other people's changes, so I've posted my entire version below: take what you want from it.

Code: Select all

# -*- coding: utf-8 -*-
"""
***************************************************************************
*                                                                         *
*   This widget makes an interactively moveable cross-section of the      *
*   currently visible objects in the currently active document. The       *
*   cross-sectioning plane is specified by its normal, and the cross-     *
*   section can be moved along that normal using a slider bar. It can     *
*   show the cross-section either as an outline or a view of the sliced   *
*   objects. To run the macro, first download it from this site and       *
*   install it in your macros directory, then use the menu to call up     *
*   your list of macros and double-click on this one. It will display     *
*   a default cross-section and pop up a window to enable you to set      *
*   the cross-sectioning parameters. Closing the pop-up window will       *
*   restore the scene to its previous state before the macro was          *
*   started.                                                              *
*                                                                         *
*   While the slider has the focus, the up or right keyboard arrow will   *
*   increase the position by 0.1%, the Page Up key will increase the      *
*   position by 1%, the down or left keyboard arrow will decrease the     *
*   position by 0.1%, and the Page Down key will decrease the position by *
*   1%.                                                                   *
*                                                                         *
***************************************************************************
*   Copyright (c) 2016 Richard P. Parkins, M. A.                          *
*                                                                         *
*   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.                                 *
*                                                                         *
*   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                                                                   *
***************************************************************************
"""
__title__   = "Cross-Section"
__author__  = "aleph0"
__version__ = "00.02"
__date__    = "30/08/2021"

__Comment__ = "Dynamic cross section viewer"
__Wiki__ = "http://www.freecadweb.org/wiki/index.php?title=Macro_cross_section"
__Help__ = "see first few lines of macro text"
__Status__ = "stable"
__Requires__ = "freecad 0.15"

# OS: Ubuntu 14.04.3 LTS
# Word size of OS: 64-bit
# Word size of FreeCAD: 64-bit
# Version: 0.15.4671 (Git)
# Branch: releases/FreeCAD-0-15
# Hash: 244b3aef360841646cbfe80a1b225c8b39c8380c
# Python version: 2.7.6
# Qt version: 4.8.6
# Coin version: 4.0.0a
# OCC version: 6.8.0.oce-0.17

from FreeCAD import Base

import PySide
from PySide import QtCore, QtGui
import FreeCADGui

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)


width = 350 # width of our window
height = 310 # height of our window
global FreeCADRootWindow # main window before we start

# This is the interactive window that the macro creates
# Its main function is to have a close box and tidy up when closed
class CrossSectionWindow(PySide.QtGui.QMainWindow):

    # automagically called when the window is created
    def __init__(self):
        Gui.updateGui() # remove menu
        super(CrossSectionWindow, self).__init__()
        self.setWindowFlags(PySide.QtCore.Qt.WindowStaysOnTopHint)
        self.setWindowTitle(_translate(
            "MainWindow", "Cross-section", None))

        # Create and set the window's widget, which does all the work
        self.child = CrossSection(self)
        self.setCentralWidget(self.child)
        self.child.initUI(self)
        if self.child.startup_failed :
            self.destroy()
        else:
            # Position our window relative to the FreeCAD root
            self.setPosition(FreeCADRootWindow)
            self.child.show()
            self.show()

    # User closed the window, tidy up
    def closeEvent(self, event) :
        self.child.restoreObjects()

    # Set a sensible default position for the window
    # With FreeCAD's default layout, this will be over the docking area
    # so it will not obscure the 3D view
    def setPosition(self, parent) :
        geom = parent.geometry()
        xpos = geom.left() + 50
        ypos = geom.center().y() - height / 2
        self.setGeometry(xpos, ypos, width, height)
        self.setFixedSize(width, height)

# This is the widget which does almost all of the work
# Widgets don't have close boxes, so closing is dealt with in CrossSectionWindow
class CrossSection(PySide.QtGui.QWidget):

    # Lay out the interactive elements
    def initUI(self, parent):

        self.parent = parent
        self.timer = PySide.QtCore.QTime()
        self.timer.start()

        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(10)
        font.setWeight(10)
        font.setBold(True)

        self.hideObjects()

        margin = 10
        alw = 20 # axis label width
        sbp = margin + alw + margin # spin boxes to right of axis labels
        slw = width - 2 * margin # width of slider and progress bar
        ypos = margin

        self.setObjectName(_fromUtf8("CrossSection"))

        # The cross-section plane is defined by its normal
        # The length of the normal is immaterial as long as it is nonzero
        self.label_1 = QtGui.QLabel(self)
        self.label_1.setGeometry(QtCore.QRect(margin, ypos, slw, 22)) 
        self.label_1.setObjectName(_fromUtf8("label_1"))
        self.label_1.setText(_translate(
            "MainWindow", "Sliding axis direction", None))
        self.label_1.setToolTip(_translate(
            "MainWindow",
            "Cross-section is taken perpendicular to this axis", None))
        ypos = ypos + 30

        self.label_2 = QtGui.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(margin, ypos, alw, 25))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.label_2.setText(_translate("MainWindow", "X", None))

        self.doubleSpinBox_X = QtGui.QDoubleSpinBox(self)
        self.doubleSpinBox_X.setGeometry(QtCore.QRect(sbp, ypos, 80, 25))
        self.doubleSpinBox_X.setMinimum(-10000.0)
        self.doubleSpinBox_X.setMaximum(10000.0)
        self.doubleSpinBox_X.setValue(0.0)
        self.doubleSpinBox_X.setSingleStep(1)
        self.doubleSpinBox_X.setObjectName(_fromUtf8("doubleSpinBox_X"))
        self.doubleSpinBox_X.valueChanged.connect(
           self.on_doubleSpinBox_X_valueChanged)
        self.doubleSpinBox_X.setToolTip(_translate(
            "MainWindow", "Sliding axis X", None))
        ypos = ypos + 30

        self.label_3 = QtGui.QLabel(self)
        self.label_3.setGeometry(QtCore.QRect(margin, ypos, alw, 25))
        self.label_3.setObjectName(_fromUtf8("label_3"))
        self.label_3.setText(_translate("MainWindow", "Y", None))

        self.doubleSpinBox_Y = QtGui.QDoubleSpinBox(self)
        self.doubleSpinBox_Y.setGeometry(QtCore.QRect(sbp, ypos, 80, 25))
        self.doubleSpinBox_Y.setMinimum(-10000.0)
        self.doubleSpinBox_Y.setMaximum(10000.0)
        self.doubleSpinBox_Y.setValue(0.0)
        self.doubleSpinBox_Y.setSingleStep(1)
        self.doubleSpinBox_Y.setObjectName(_fromUtf8("doubleSpinBox_Y"))
        self.doubleSpinBox_Y.valueChanged.connect(
           self.on_doubleSpinBox_Y_valueChanged)
        self.doubleSpinBox_Y.setToolTip(_translate(
            "MainWindow", "Sliding axis Y", None))
        ypos = ypos + 30

        self.label_4 = QtGui.QLabel(self)
        self.label_4.setGeometry(QtCore.QRect(margin, ypos, alw, 25))
        self.label_4.setObjectName(_fromUtf8("label_4"))
        self.label_4.setText(_translate("MainWindow", "Z", None))

        self.doubleSpinBox_Z = QtGui.QDoubleSpinBox(self)
        self.doubleSpinBox_Z.setGeometry(QtCore.QRect(sbp, ypos, 80, 25))
        self.doubleSpinBox_Z.setMinimum(-10000.0)
        self.doubleSpinBox_Z.setMaximum(10000.0)
        self.doubleSpinBox_Z.setValue(0.5)
        self.doubleSpinBox_Z.setSingleStep(1)
        self.doubleSpinBox_Z.setObjectName(_fromUtf8("doubleSpinBox_Z"))
        self.doubleSpinBox_Z.valueChanged.connect(
           self.on_doubleSpinBox_Z_valueChanged)
        self.doubleSpinBox_Z.setToolTip(
            _translate("MainWindow", "Sliding axis Z", None))
        ypos = ypos + 40

        # Make the interactive slider control
        # As you move this slider with the mouse, the cross-section slides
        # through the model
        self.label_5 = QtGui.QLabel(self)
        self.label_5.setGeometry(QtCore.QRect(margin, ypos, slw, 22))
        self.label_5.setObjectName(_fromUtf8("label_5"))
        self.label_5.setText(_translate(
            "MainWindow", "Position along axis", None))
        ypos = ypos + 30

        self.horizontalSlider = QtGui.QSlider(self)
        self.horizontalSlider.setGeometry(QtCore.QRect(margin, ypos, slw, 20))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setInvertedAppearance(False)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.horizontalSlider.setPageStep(10)
        self.horizontalSlider.setRange(0, 1000)
        self.horizontalSlider.setValue(int(self.fraction * 1000.0))
        self.horizontalSlider.setToolTip(_translate(
            "MainWindow", "Slide to move cross-section along axis", None))

        # must be called after setValue()
        self.horizontalSlider.valueChanged.connect(self.on_horizontal_slider)
        ypos = ypos + 30

        self.progressBar_1 = QtGui.QProgressBar(self)
        self.progressBar_1.setGeometry(QtCore.QRect(margin, ypos, slw, 23))
        self.progressBar_1.setValue(int(self.fraction * 100.0))
        self.progressBar_1.setOrientation(QtCore.Qt.Horizontal)
        self.progressBar_1.setAlignment(QtCore.Qt.AlignCenter)
        self.progressBar_1.setObjectName(_fromUtf8("progressBar_1"))
        self.progressBar_1.setToolTip(_translate(
            "MainWindow", "Percent position of cross-section", None))
        ypos = ypos + 40

        # Select the display format for the cross-section
        # This button shows a wire line in the cross-section plane
        self.radioButton_1 = QtGui.QRadioButton(self)
        self.radioButton_1.setGeometry(QtCore.QRect(margin, ypos, slw, 20))
        self.radioButton_1.setText(_fromUtf8("Outline"))
        self.radioButton_1.setChecked(True)
        self.radioButton_1.toggled.connect(self.onRadioButton)
        self.radioButton_1.setObjectName(_fromUtf8("radioButton_1"))
        self.radioButton_1.setToolTip(_translate(
            "MainWindow", "Make cross-section as wire outline", None))
        ypos = ypos + 30

        # Select the display format for the cross-section
        # This button shows a normal 3D display with everything above the
        # cross-section plane cut away
        self.radioButton_2 = QtGui.QRadioButton(self)
        self.radioButton_2.setGeometry(QtCore.QRect(margin, ypos, slw, 20))
        self.radioButton_2.setText(_fromUtf8("Cut objects"))
        self.radioButton_2.setChecked(False)
        self.radioButton_2.toggled.connect(self.onRadioButton)
        self.radioButton_2.setObjectName(_fromUtf8("radioButton_2"))
        self.radioButton_2.setToolTip(_translate(
            "MainWindow", "Make cross-section as cut objects", None))

    # Called at macro start up by initUI()
    def hideObjects(self):
        # Initialise the cross-section state variables
        self.startup_failed = False
        self.fraction = 0.5
        self.axisX = 0.0
        self.axisY = 0.0
        self.axisZ = 1.0
        self.cross_section_type = 1

        # We must have something to do a cross-section on
        if App.ActiveDocument is None :
            QtGui.QMessageBox.warning(None, _translate("MainWindow",
                "Cross-section", None),
                _translate("MainWindow", "There is no Active Document\n" +
                    "Create one and run this macro again.", None),
                QtGui.QMessageBox.Cancel,
                QtGui.QMessageBox.Cancel)
            self.startup_failed = True
            self.parent.destroy() # This will close the window
        else :

            # Make a list of the user's objects
            # WARNING!!
            # This list is persistent. We'll get confused if the user deletes or
            # adds objects while the macro is active
            self.oblist = App.ActiveDocument.Objects

            # Create the cross-section object
            self.cs = FreeCAD.ActiveDocument.addObject("Part::Feature",
                "Generated__cross-section")
            self.OriginalVisibilities = list()
            self.xmin = 1e30
            self.xmax = -1e30
            self.ymin = 1e30
            self.ymax = -1e30
            self.zmin = 1e30
            self.zmax = -1e30
            n = len(self.oblist)
            # Make a list of the visible objects and make them invisible while
            # the macro is active
            # Also we compute the bounding box of the model
            for i in range(n):
                vis = self.oblist[i].ViewObject.Visibility
                self.OriginalVisibilities.append(vis)
                if vis :
                    self.oblist[i].ViewObject.Visibility=False
                    b = self.oblist[i].Shape.BoundBox
                    if b.XMin < self.xmin :
                        self.xmin = b.XMin
                    if b.XMax > self.xmax :
                        self.xmax = b.XMax
                    if b.YMin < self.ymin :
                        self.ymin = b.YMin
                    if b.YMax > self.ymax :
                        self.ymax = b.YMax
                    if b.ZMin < self.zmin :
                        self.zmin = b.ZMin
                    if b.ZMax > self.zmax :
                        self.zmax = b.ZMax
            # Moan and give up if there is nothing to cross-section
            if self.xmax <= self.xmin \
            or self.ymax <= self.ymin \
            or self.zmax <= self.zmin :
                QtGui.QMessageBox.warning(None, _translate("MainWindow",
                    "Cross-section", None),
                    _translate("MainWindow",
                    "There are no visible solid objects\n" +
                    "Create some and run this macro again.", None),
                    QtGui.QMessageBox.Cancel,
                    QtGui.QMessageBox.Cancel)
                self.restoreObjects()
                self.startup_failed = True
                self.parent.destroy() # This will close the window
            else :
                # Trigger initial display
                self.updateAxis()

    # Called when macro is closed
    # Restore the original visibility of the user's objects
    # and destroy our cross-section object
    def restoreObjects(self):
        n = len(self.oblist)
        for i in range(n):
            self.oblist[i].ViewObject.Visibility = self.OriginalVisibilities[i]
        App.ActiveDocument.removeObject("Generated__cross_section")

    # Something has changed, recalculate the cross-section
    def updateGui(self):
        PySide.QtGui.QApplication.setOverrideCursor(PySide.QtGui.QCursor(PySide.QtCore.Qt.WaitCursor))

        # default to no visible cross-ection
        self.cs.ViewObject.Visibility = False

        # check if the sliding axis is invalid
        if self.xdir == 0.0 and self.ydir == 0.0 and self.zdir == 0.0 :
            QtGui.QMessageBox.warning(None, _translate("MainWindow",
                "Cross-section", None),
                _translate("MainWindow", "The sliding axis has zero length\n" +
                    "Please set a valid axis.", None),
                QtGui.QMessageBox.Ok,
                QtGui.QMessageBox.Ok)
        else :

            # First we compute the 0% and 100% positions on the sliding axis
            if self.xdir < 0.0 :
                x = self.xmax + self.fraction * self.xdir
            else :
                x = self.xmin + self.fraction * self.xdir
            if self.ydir < 0.0 :
                y = self.ymax + self.fraction * self.ydir
            else :
                y = self.ymin + self.fraction * self.ydir
            if self.zdir < 0.0 :
                z = self.zmax + self.fraction * self.zdir
            else :
                z = self.zmin + self.fraction * self.zdir
            r = 2 * max(self.xmax - self.xmin, self.ymax - self.ymin,
                        self.zmax - self.xmin)

            # Create a big enough disc in the cross-section plane
            c = Part.makeCircle(r, Base.Vector(x, y, z),
                 Base.Vector(self.xdir,  self.ydir,  self.zdir))
            f = Part.Face(Part.Wire(c))
            l = list() # list for cross-section parts
            n = len(self.oblist)
            something = False
            if self.cross_section_type == 1 :
                # wire line cross-section
                for i in range(n):
                    if self.OriginalVisibilities[i] :
                        ob = self.oblist[i].Shape.section(f)
                        # check for valid section part
                        if ob.BoundBox.XMin <= ob.BoundBox.XMax :
                            l.append(ob)
                            something = True
            else :
                # cut shape cross-section
                # extrude our cross-ection disc into a cylinder
                cyl = f.extrude(Base.Vector(self.xdir,  self.ydir,  self.zdir))
                for i in range(n):
                    if self.OriginalVisibilities[i] :
                        ob = self.oblist[i].Shape.cut(cyl)
                        if ob.isValid() and ob.Volume > 0.0 :
                            l.append(ob)
                            something = True

            if something :
                s = Part.makeCompound(l)
                if s.isValid() :
                    self.cs.Shape = s
                    self.cs.ViewObject.Visibility = True
            FreeCADGui.updateGui()
        PySide.QtGui.QApplication.restoreOverrideCursor()

    # User changed axis vector
    # Compute a new axis vector whose length just covers the model
    def updateAxis(self):
        ldir = 0.0
        if self.axisX != 0.0 :
            ldir = (self.xmax - self.xmin) / abs(self.axisX)
        if self.axisY != 0.0 :
            ldir = max(ldir, (self.ymax - self.ymin) / abs(self.axisY))
        if self.axisZ != 0.0 :
            ldir = max(ldir, (self.zmax - self.zmin) / abs(self.axisZ))
        self.xdir = self.axisX * ldir
        self.ydir = self.axisY * ldir
        self.zdir = self.axisZ * ldir
        self.updateGui() # recalculate the cross-section

    def on_horizontal_slider(self, val):
        # This bit of magic improves the interactivity if the scene
        # is complex and the cross-section takes a long time to redraw.
        # It prevents stacking updates while redrawing.
        self.horizontalSlider.setTracking(False)
        while True:
            val = self.horizontalSlider.sliderPosition()
            self.fraction = val / 1000.0
            self.progressBar_1.setValue(self.fraction * 100.0)
            self.updateGui()
            if self.horizontalSlider.sliderPosition() == val: break
        self.horizontalSlider.setTracking(True)

    def on_doubleSpinBox_X_valueChanged(self, val):
        self.axisX = val
        self.updateAxis()

    def on_doubleSpinBox_Y_valueChanged(self, val):
        self.axisY = val
        self.updateAxis()

    def on_doubleSpinBox_Z_valueChanged(self, val):
        self.axisZ = val
        self.updateAxis()

    def onRadioButton(self, wasChecked) :
        if self.radioButton_1.isChecked() :
            self.cross_section_type = 1
        else :
            self.cross_section_type = 2
        self.updateGui()

#######################################

# Find FreeCAD's root window
FreeCADRootWindow = Gui.getMainWindow()

# Create the window and start it
myWidget = CrossSectionWindow()

# The CrossSectionWindow will do all the work
User avatar
thomas-neemann
Veteran
Posts: 11801
Joined: Wed Jan 22, 2020 6:03 pm
Location: Osnabrück DE 🇩🇪
Contact:

Re: cross-section macro

Post by thomas-neemann »

aleph0 wrote: Mon Aug 30, 2021 8:21 pm
thank you very much it solved my problem


https://forum.freecadweb.org/viewtopic.php?f=3&t=61764
Gruß Dipl.-Ing. (FH) Thomas Neemann

https://www.youtube.com/@thomasneemann5 ... ry=freecad
mario52
Veteran
Posts: 4673
Joined: Wed May 16, 2012 2:13 pm

Re: Sezione Dinamica

Post by mario52 »

Hi
aleph0 wrote: Mon Aug 30, 2021 8:21 pm I see the macro has been modified quite a lot since I first posted it
why not continue upgrade your macro Macro_cross_section to benefit all change

here other correction cross section macro does not work on bodies within a part container for bodies but the multi colour adding by @Gift hare "deleted"

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
Post Reply