1

背景:我正在为 FreeCAD 编写一个宏 python 脚本。此代码打开一个对话框,提供有关草图几何形状的信息,例如惯性矩阵和面积。

我的问题:我正在尝试获取脚本末尾的总面积。目前,它给出了每个几何图形的结果,这没问题,但我希望在我的宏脚本对话框中有一个完整的部分。

我已经尝试过:我尝试为每个几何图形创建一个 for 循环,以计算面积并将其存储为变量。我也试图把它放在已经存在的 for 循环中。我最终遇到了语法错误。

https://i.stack.imgur.com/ngRdu.png

import FreeCADGui as Gui
import Part

from PySide2 import QtWidgets

class MyMsgBox(QtWidgets.QDialog):
    """This function defines a custom message box with a scrollable text edit to display message
    The displayed text can be get/set with the 'content' property"""

    def __init__(self, parent=None, title=None, msg=""):
        super(MyMsgBox, self).__init__(parent)
        self._content = msg
        if title:
            self.setWindowTitle(title)
        lay = QtWidgets.QVBoxLayout()
        self.textBox = QtWidgets.QTextEdit()
        self.textBox.setReadOnly(True)
        self.textBox.setText(self._content)
        lay.addWidget(self.textBox)
        btnBox = QtWidgets.QDialogButtonBox()
        btnBox.setStandardButtons(btnBox.Ok)
        lay.addWidget(btnBox)
        btnBox.accepted.connect(self.accept)
        self.setLayout(lay)
        if parent:
            self.resize(parent.width()*0.2, parent.height()*0.2)

    @property
    def content(self):
        return self._content

    @content.setter
    def content(self, msg):
        self._content = msg
        self.textBox.setText(self._content)

def check_self_intersect(shape):
    """Check if a shape is self-intersecting"""
    try:
        shape.check(True)
        return False
    except ValueError as e:
        if 'SelfIntersect' in str(e):
            return True
        return False
try:
    sketch = ActiveSketch # This macro processes active sketch (one that is currently edited, or last edited)
except NameError:
    sketch = None
msg = '' # Init message with empty string
title = 'Error'

if not sketch : # If no active sketch to work on ...
    msg = 'No active sketch' # ... just update the message to warn user
else: # If an active sketch is available

    openverticescount=len(sketch.OpenVertices)
    check_result=check_self_intersect(sketch.Shape)

    if (openverticescount > 0 or check_result == True):
        msg = 'Error: Sketch is not closed or intersects'
    else:
        skNorm = sketch.Placement.Rotation.multVec(App.Vector(0,0,1)) # Determine normal vector of sketch
        title = "Properties of {}".format(sketch.Name)
        target  = [sketch.Shape] # Target shape is sketch shape. Make it a list so it's compatible with the further 'for' loop
        if isinstance(target[0], Part.Compound): # If sketch has multiple geometries ...
            target = target[0].SubShapes # ... target each shape individualy
        for obj in target: # Go through the targeted shapes and for each ...
            obj = Part.makeFace(obj, 'Part::FaceMakerBullseye') # ... convert shape to a face ...
            
            area = str(round(obj.Area/645.16, 3))

            msg = msg + 'Area : ' + area + ' inches^2 ' + '\n' # ... to get area ...
            msg = msg + 'Center of mass : ' + str(obj.CenterOfMass) + '\n' # ... and center of mass coordinates ...
            obj = obj.extrude(skNorm*0.000254) ### ... then convert to solid (extrude 1 mm) ...
            msg = msg + 'Moments of inertia (inches ^ 4): ' + '\n' # ... to get its moment of inertia
            msg = msg + ' Lxx: ' + str(round(obj.MatrixOfInertia.A[0]/10572278.2/0.00001, 3)) + ' Lxy: ' + str(round(obj.MatrixOfInertia.A[4]/10572278.2/0.00001, 3)) + ' Lxz: ' + str(round(obj.MatrixOfInertia.A[8]/10572278.2/0.00001, 3))+ '\n'
            msg = msg + ' Lyx: ' + str(round(obj.MatrixOfInertia.A[1]/10572278.2/0.00001, 3)) + ' Lyy: ' + str(round(obj.MatrixOfInertia.A[5]/10572278.2/0.00001, 3)) + ' Lyz: ' + str(round(obj.MatrixOfInertia.A[9]/10572278.2/0.00001, 3))+ '\n'
            msg = msg + ' Lzx: ' + str(round(obj.MatrixOfInertia.A[2]/10572278.2/0.00001, 3)) + ' Lzy: ' + str(round(obj.MatrixOfInertia.A[6]/10572278.2/0.00001, 3)) + ' Lzz: ' + str(round(obj.MatrixOfInertia.A[10]/10572278.2/0.00001, 3))+ '\n\n'

#QtWidgets.QMessageBox.information(Gui.getMainWindow(), 'Center of Mass/Moment of Inertia', msg) # Display the message to the use rin a modal information box dialog
MyMsgBox(Gui.getMainWindow(), title, msg).exec_() ```



4

0 回答 0