Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

In diesem Forum Fragen und Diskussionen in Deutsch
Forum rules
Foren-Regeln und hilfreiche Informationen

WICHTIG: Bitte zuerst lesen, bevor Sie posten
mario52
Veteran
Posts: 4690
Joined: Wed May 16, 2012 2:13 pm

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by mario52 »

Hi
thank for upgrade the macro make by aleph0 (and not mario i ave just add one feature and Sam correct for the 0.17 FC version)
but i have error see Sezione Dinamica

and with your modification: first test
CrossSection00.png
CrossSection00.png (11.05 KiB) Viewed 3035 times
and after same correction Sam FC stop with the same error window

(ps: the original version does not work anymore ??)

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.
freecad-heini-1
Veteran
Posts: 7790
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by freecad-heini-1 »

mario52 wrote: Thu Aug 31, 2017 8:58 am (ps: the original version does not work anymore ??)
Dear Mario,
thank you for your answer. The original macro still works, but without colours.
@Gift changed the macro and it worked if the parts do not touch each other, please look at this picture:
Image
If the parts are touching each other, the colour from the cutting plane is wrong, and the face is melted into one, no single faces with the part colour, please see this picture:
Image

Is it possible to optimize the macro?

Thank you and best regards
Wilfried
mario52
Veteran
Posts: 4690
Joined: Wed May 16, 2012 2:13 pm

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by mario52 »

hi freecad-heini-1

I think Gift is more competent than me

@Gift
the upgrade is finished ? (for update the wiki page)

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.
User avatar
Gift
Posts: 769
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by Gift »

Thx 4 your trust. No, the upgrade is not finished. I'm going to revise it. But now is the time to drink beer.
User avatar
Gift
Posts: 769
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by Gift »

1. If I replace MultiFuse by Part::Compound, is the fusion issue solved. => Part_compound.png
2. But multi-color-objects falls to anarchy. => Anarchy.png
3. The very next step is to cut all objects with Part:Cut. The cut face will dye another color(selectable). Is this solution ok? => A_lot_of_PartCuts.png, A_lot_of_PartCuts2.png

I need more time…
kind regards Benjamin
Attachments
A_lot_of_PartCuts2.png
A_lot_of_PartCuts2.png (7.59 KiB) Viewed 2926 times
A_lot_of_PartCuts.png
A_lot_of_PartCuts.png (18.5 KiB) Viewed 2926 times
Anarchy.png
Anarchy.png (16.73 KiB) Viewed 2926 times
Part_compound.png
Part_compound.png (4.48 KiB) Viewed 2926 times
freecad-heini-1
Veteran
Posts: 7790
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by freecad-heini-1 »

Gift wrote: Mon Sep 04, 2017 7:46 pm 1. If I replace MultiFuse by Part::Compound, is the fusion issue solved. => Part_compound.png
2. But multi-color-objects falls to anarchy. => Anarchy.png
3. The very next step is to cut all objects with Part:Cut. The cut face will dye another color(selectable). Is this solution ok? => A_lot_of_PartCuts.png, A_lot_of_PartCuts2.png

I need more time…
kind regards Benjamin
Danke sehr Benjamin. 8-)
User avatar
Gift
Posts: 769
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by Gift »

A update to test.

Todo:
* optimize the loop (initialize some objects out of the loop)
* some error messages with outline
* cut object: “Cannot compute Inventor representation for the shape of Compound”. Maybe some very empty shapes?

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.                                                              *
*                                                                         *
***************************************************************************
*   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.04"
__date__    = "29/01/2016" "10/06/2016" "29/09/2016 * 2"
 
__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
 
import PySide
from PySide import QtCore, QtGui
import FreeCADGui
from FreeCAD import Base

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):
        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

        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, 62, 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, 62, 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, 62, 25))
        self.doubleSpinBox_Z.setMinimum(-10000.0)
        self.doubleSpinBox_Z.setMaximum(10000.0)
        self.doubleSpinBox_Z.setValue(1.0)
        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-50, 20))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setInvertedAppearance(False)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.horizontalSlider.setRange(0, 100)
        self.horizontalSlider.setValue(int(self.fraction * 100.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-50, 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
 
##################################    add
        self.SpinBox_PBar = QtGui.QSpinBox(self)
        self.SpinBox_PBar.setGeometry(QtCore.QRect(sbp+255, ypos-40, 45, 23))
        self.SpinBox_PBar.setMinimum(0.0)
        self.SpinBox_PBar.setMaximum(100.0)
        self.SpinBox_PBar.setValue(int(self.fraction * 100.0))
        self.SpinBox_PBar.setSingleStep(1)
        self.SpinBox_PBar.setObjectName(_fromUtf8("SpinBox_PBar"))
        self.SpinBox_PBar.valueChanged.connect(self.on_SpinBox_PBar_valueChanged)
        self.SpinBox_PBar.setToolTip(_translate(
            "MainWindow", "Sliding percent", None))
#################################    add

        # 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))

##################################
        #Keep the sectional view
        self.CB_00 = QtGui.QCheckBox(self)
        self.CB_00.setText(_fromUtf8("Keep the sectional view"))
        self.CB_00.setGeometry(QtCore.QRect(margin+168, ypos-30, slw, 20))
        self.CB_00.setObjectName(_fromUtf8("CB_00"))
        self.CB_00.setChecked(False)
        self.CB_00.setToolTip(_translate(
            "MainWindow", "Keep the sectional view or erase", 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 = 1000.0
            self.xmax = -1000.0
            self.ymin = 1000.0
            self.ymax = -1000.0
            self.zmin = 1000.0
            self.zmax = -1000.0
#            n = 0
#            for p in self.oblist: # stupid Python list has no length function
#                n = n + 1
############################# Skip the <group object> ########################         # add
            b0 = []
            for x0 in self.oblist:
                if str(x0) !=  "<group object>":
                    b0.append(x0)
            self.oblist = b0
            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 :
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        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
                App.ActiveDocument.removeObject("Generated__cross_section")
                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 = 0
        for p in self.oblist: # stupid Python list has no length function
            n = n + 1
        for i in range(n):
            self.oblist[i].ViewObject.Visibility = self.OriginalVisibilities[i]
        try:
            if self.CB_00.isChecked() == False:
                App.ActiveDocument.removeObject("Generated__cross_section")
        except Exception:
            None
    # Something has changed, recalculate the cross-section
    def updateGui(self):
 
        # 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)

            # Display the dimensions
            dimDep = "X "+str(x)+" mm , Y "+str(y)+" mm , Z "+str(z)+" mm"
            App.Console.PrintMessage(dimDep + "\n")


            # 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
            h = list()
            n = 0
            for p in self.oblist: # stupid Python list has no length function
                n = n + 1
            something = False
            if self.cross_section_type == 1 :
                # wire line cross-section
                for i in range(n):
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        if self.OriginalVisibilities[i] :
							ob = FreeCAD.ActiveDocument.addObject("Part::Feature")
							ob.ViewObject.DiffuseColor = self.oblist[i].ViewObject.DiffuseColor
							ob.Shape = self.oblist[i].Shape.section(f)
                            # check for valid section part
							if ob.Shape.BoundBox.XMin <= ob.Shape.BoundBox.XMax :
								l.append(ob)
								something = True
							else:
								FreeCAD.ActiveDocument.removeObject(ob.Name)
            else :
                # cut shape cross-section
                # extrude our cross-ection disc into a cylinder
                cyl = f.extrude(Base.Vector(self.xdir,  self.ydir,  self.zdir))
                doc = FreeCAD.ActiveDocument
                for i in range(n):
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        if self.OriginalVisibilities[i] :
							acut  = doc.addObject("Part::Cut","Cut")
							abase = Draft.clone(self.oblist[i]) 
							atool = doc.addObject("Part::Feature")
							atool.Shape = cyl
							atool.ViewObject.ShapeColor=(0.25,0.57,0.35)
							doc.recompute()
							acut.Base = abase
							acut.Tool = atool
							acut.ViewObject.DiffuseColor = abase.ViewObject.DiffuseColor
							doc.recompute()	
							ob = doc.addObject("Part::Feature")
							ob.Shape = acut.Shape
							ob.ViewObject.DiffuseColor = acut.ViewObject.DiffuseColor 
							doc.recompute()		
							doc.removeObject(acut.Name)
							doc.recompute()	
							doc.removeObject(abase.Name)
							doc.recompute()	
							doc.removeObject(atool.Name)
							doc.recompute()	
							if ob.Shape.isValid() and ob.Shape.Volume > 0.0 :
								l.append(ob)
								something = True
							else:
								doc.removeObject(ob.Name)
 
            if something :
				feature = FreeCAD.ActiveDocument.addObject("Part::Compound","Compound")
				feature.Links = l
				FreeCAD.ActiveDocument.recompute()
				if feature.Shape.isValid() :
					self.cs.Shape = feature.Shape.copy()
					self.cs.ViewObject.DiffuseColor = feature.ViewObject.DiffuseColor
					self.cs.ViewObject.Visibility = True
				for od in l:
					FreeCAD.ActiveDocument.removeObject(od.Name)
					FreeCAD.ActiveDocument.recompute()
				FreeCAD.ActiveDocument.recompute()
				FreeCAD.ActiveDocument.removeObject(feature.Name)
            FreeCADGui.updateGui()
 
    # 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):
        self.fraction = val / 100.0
        self.progressBar_1.setValue(val)
        self.SpinBox_PBar.setValue(val)
        self.updateGui()
 
    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 on_SpinBox_PBar_valueChanged(self, val):
        self.progressBar_1.setValue(val)
        self.horizontalSlider.setValue(int(val))
        self.updateGui()
       

    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 
Attachments
cross_section_with_color.zip
(5.84 KiB) Downloaded 113 times
mario52
Veteran
Posts: 4690
Joined: Wed May 16, 2012 2:13 pm

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by mario52 »

Hi

the beer are beautiful effect

thanks for your work i have upgrade the wiki page

mario

EDIT: 21:42 Paris time

i have error
1: Error Draft i add in the macro import Draft
after
2:
X 0.0 mm , Y 0.0 mm , Z 5.0 mm
Traceback (most recent call last):
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 566, in <module>
myWidget = CrossSectionWindow()
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 102, in __init__
self.child.initUI(self)
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 140, in initUI
self.hideObjects()
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 386, in hideObjects
self.updateAxis()
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 527, in updateAxis
self.updateGui() # recalculate the cross-section
File "C:/Users/xxxx/AppData/Roaming/FreeCAD/Macro/Macro_cross_section.FCMacro", line 458, in updateGui
ob.Shape = self.oblist.Shape.section(f)
<class 'Part.OCCError'>: Base shape is null


OS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6712 (Git)
Build type: Release
Branch: releases/FreeCAD-0-16
Hash: da2d364457257a7a8c6fb2137cea12c45becd71a
Python version: 2.7.8
Qt version: 4.8.7
Coin version: 4.0.0a
OCC version: 6.8.0.oce-0.17

with FC017 same FreeCAD stop

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.
freecad-heini-1
Veteran
Posts: 7790
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by freecad-heini-1 »

Gift wrote: Wed Sep 06, 2017 3:02 pm A update to test.

Todo:
* optimize the loop (initialize some objects out of the loop)
* some error messages with outline
* cut object: “Cannot compute Inventor representation for the shape of Compound”. Maybe some very empty shapes?

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.                                                              *
*                                                                         *
***************************************************************************
*   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.04"
__date__    = "29/01/2016" "10/06/2016" "29/09/2016 * 2"
 
__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
 
import PySide
from PySide import QtCore, QtGui
import FreeCADGui
from FreeCAD import Base

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):
        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

        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, 62, 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, 62, 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, 62, 25))
        self.doubleSpinBox_Z.setMinimum(-10000.0)
        self.doubleSpinBox_Z.setMaximum(10000.0)
        self.doubleSpinBox_Z.setValue(1.0)
        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-50, 20))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setInvertedAppearance(False)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.horizontalSlider.setRange(0, 100)
        self.horizontalSlider.setValue(int(self.fraction * 100.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-50, 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
 
##################################    add
        self.SpinBox_PBar = QtGui.QSpinBox(self)
        self.SpinBox_PBar.setGeometry(QtCore.QRect(sbp+255, ypos-40, 45, 23))
        self.SpinBox_PBar.setMinimum(0.0)
        self.SpinBox_PBar.setMaximum(100.0)
        self.SpinBox_PBar.setValue(int(self.fraction * 100.0))
        self.SpinBox_PBar.setSingleStep(1)
        self.SpinBox_PBar.setObjectName(_fromUtf8("SpinBox_PBar"))
        self.SpinBox_PBar.valueChanged.connect(self.on_SpinBox_PBar_valueChanged)
        self.SpinBox_PBar.setToolTip(_translate(
            "MainWindow", "Sliding percent", None))
#################################    add

        # 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))

##################################
        #Keep the sectional view
        self.CB_00 = QtGui.QCheckBox(self)
        self.CB_00.setText(_fromUtf8("Keep the sectional view"))
        self.CB_00.setGeometry(QtCore.QRect(margin+168, ypos-30, slw, 20))
        self.CB_00.setObjectName(_fromUtf8("CB_00"))
        self.CB_00.setChecked(False)
        self.CB_00.setToolTip(_translate(
            "MainWindow", "Keep the sectional view or erase", 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 = 1000.0
            self.xmax = -1000.0
            self.ymin = 1000.0
            self.ymax = -1000.0
            self.zmin = 1000.0
            self.zmax = -1000.0
#            n = 0
#            for p in self.oblist: # stupid Python list has no length function
#                n = n + 1
############################# Skip the <group object> ########################         # add
            b0 = []
            for x0 in self.oblist:
                if str(x0) !=  "<group object>":
                    b0.append(x0)
            self.oblist = b0
            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 :
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        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
                App.ActiveDocument.removeObject("Generated__cross_section")
                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 = 0
        for p in self.oblist: # stupid Python list has no length function
            n = n + 1
        for i in range(n):
            self.oblist[i].ViewObject.Visibility = self.OriginalVisibilities[i]
        try:
            if self.CB_00.isChecked() == False:
                App.ActiveDocument.removeObject("Generated__cross_section")
        except Exception:
            None
    # Something has changed, recalculate the cross-section
    def updateGui(self):
 
        # 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)

            # Display the dimensions
            dimDep = "X "+str(x)+" mm , Y "+str(y)+" mm , Z "+str(z)+" mm"
            App.Console.PrintMessage(dimDep + "\n")


            # 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
            h = list()
            n = 0
            for p in self.oblist: # stupid Python list has no length function
                n = n + 1
            something = False
            if self.cross_section_type == 1 :
                # wire line cross-section
                for i in range(n):
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        if self.OriginalVisibilities[i] :
							ob = FreeCAD.ActiveDocument.addObject("Part::Feature")
							ob.ViewObject.DiffuseColor = self.oblist[i].ViewObject.DiffuseColor
							ob.Shape = self.oblist[i].Shape.section(f)
                            # check for valid section part
							if ob.Shape.BoundBox.XMin <= ob.Shape.BoundBox.XMax :
								l.append(ob)
								something = True
							else:
								FreeCAD.ActiveDocument.removeObject(ob.Name)
            else :
                # cut shape cross-section
                # extrude our cross-ection disc into a cylinder
                cyl = f.extrude(Base.Vector(self.xdir,  self.ydir,  self.zdir))
                doc = FreeCAD.ActiveDocument
                for i in range(n):
                    if self.oblist[i].TypeId != str("Drawing::FeatureViewPython") :    # add
                        if self.OriginalVisibilities[i] :
							acut  = doc.addObject("Part::Cut","Cut")
							abase = Draft.clone(self.oblist[i]) 
							atool = doc.addObject("Part::Feature")
							atool.Shape = cyl
							atool.ViewObject.ShapeColor=(0.25,0.57,0.35)
							doc.recompute()
							acut.Base = abase
							acut.Tool = atool
							acut.ViewObject.DiffuseColor = abase.ViewObject.DiffuseColor
							doc.recompute()	
							ob = doc.addObject("Part::Feature")
							ob.Shape = acut.Shape
							ob.ViewObject.DiffuseColor = acut.ViewObject.DiffuseColor 
							doc.recompute()		
							doc.removeObject(acut.Name)
							doc.recompute()	
							doc.removeObject(abase.Name)
							doc.recompute()	
							doc.removeObject(atool.Name)
							doc.recompute()	
							if ob.Shape.isValid() and ob.Shape.Volume > 0.0 :
								l.append(ob)
								something = True
							else:
								doc.removeObject(ob.Name)
 
            if something :
				feature = FreeCAD.ActiveDocument.addObject("Part::Compound","Compound")
				feature.Links = l
				FreeCAD.ActiveDocument.recompute()
				if feature.Shape.isValid() :
					self.cs.Shape = feature.Shape.copy()
					self.cs.ViewObject.DiffuseColor = feature.ViewObject.DiffuseColor
					self.cs.ViewObject.Visibility = True
				for od in l:
					FreeCAD.ActiveDocument.removeObject(od.Name)
					FreeCAD.ActiveDocument.recompute()
				FreeCAD.ActiveDocument.recompute()
				FreeCAD.ActiveDocument.removeObject(feature.Name)
            FreeCADGui.updateGui()
 
    # 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):
        self.fraction = val / 100.0
        self.progressBar_1.setValue(val)
        self.SpinBox_PBar.setValue(val)
        self.updateGui()
 
    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 on_SpinBox_PBar_valueChanged(self, val):
        self.progressBar_1.setValue(val)
        self.horizontalSlider.setValue(int(val))
        self.updateGui()
       

    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 
Funktioniert bei mir leider nicht. Dennoch vielen Dank für die Mühe.
User avatar
PrzemoF
Veteran
Posts: 3520
Joined: Fri Jul 25, 2014 4:52 pm
Contact:

Re: Optischer Schnitt durch Baugruppe, z.B. für Ventilgehäuse

Post by PrzemoF »

Code: Select all

            for p in self.oblist: # stupid Python list has no length function
                n = n + 1
-->

Code: Select all

>>> a_list = []
>>> a_list.append('a')
>>> a_list.append('b')
>>> a_list.append('c')
>>> len(a_list)
3
>>> type(a_list)
<type 'list'>
Post Reply