Working with ByRef arrays in CATIA

This is not actually a script, but a solution I’ve found to a huge roadblock I encountered while trying to use Python to automate CATIA V5 using win32com AND use all funcionalities exposed to automation.

We all know it’s very easy to get started by just using late-binding (dynamic dispatch) and the more advanced users will already know that it will be not possible to use Subs that need Byref arrays. Developers of win32com related stuff are aware of the problem but not to the fact that in some applications these kind of Sub are very intensively used i.e. all subs to get triplets such as GetCoordinates of any class derived from the Point class, or GetFirstAxis of any class derived from the Plane class.
Developers state that it’s sufficient to switch to early bindig using makepy to solve the problem but in my case for CATIA V5 R19 it didn’t solve the problem at all, it even added more problems. Continue reading “Working with ByRef arrays in CATIA”

Python library for Dassault Systemes CATIA

There are already some examples on this website, which explain, how to automate Dassault Systemes CATIA V5 with Python and Microsoft COM. Yesterday Paul sent me a mail and mentioned, that he has created a Python Library, which packs a few of the COM magics into a Python library with some basic functions. It covers things like, traversing assembly structures, context manager, convert files, find elements in a part, etc. Continue reading “Python library for Dassault Systemes CATIA”

Events in Autodesk Inventor

How to listen and respond to Inventor events in Python using win32com (from http://wikihelp.autodesk.com/Inventor/enu/Community/Third_Party_Tools/the_python_page/Listening_to_Events). This example assumes you have succefully been able to connect to Inventor’s COM object If you have not, please do that first.

# used to listen to the application events and also the events for a custom button
import ctypes
import win32com.client
from win32com.client.gencache import EnsureDispatch
import pythoncom

class Events():
    def __init__(self, oApp):
        global Application
        Application = oApp
   
    #Application Events
    class IVEvent():      
        def OnQuit(self, BeforeOrAfter, Context, HandlingCode):
            print("Quiting...")
            ctypes.windll.user32.PostQuitMessage(0)
            Application.Quit()
     
    #Custom Button Events      
    class BEvent():
        def OnExecute(self, Context):
            print "Dxf Button Clicked"

class DoylePlugin():    
    oApp=EnsureDispatch("Inventor.Application")
    oApp.Visible=True
      
    DxfButton=oApp.CommandManager.ControlDefinitions.AddButtonDefinition("Dxf Update", "dxf", 4)
    DxfButton.AutoAddToGUI()
    
    Events = Events(oApp)        
    AppEvents=win32com.client.DispatchWithEvents(oApp.ApplicationEvents, Events.IVEvent)
    DxfEvents=win32com.client.DispatchWithEvents(DxfButton, Events.BEvent)
    
    pythoncom.PumpMessages()

How to automate CATIA V6 with Python on Windows

CATIA V6 can be automated in the same way like CATIA V5. You need either the comtypes module or the Pywin32 module. The next two examples show two simple programming examples by using Pywin32, which is included in the ActivePython Distribution. If you want to use another Python Distribution, you have to install this module manually.

When you run the following two scripts, CATIA V6 should be installed and already be running.

The first example prints the names (PLMExternalID) of all selected entries in a query list of the advanced search (Silver Layer):

import win32com.client

catiaObj=win32com.client.GetActiveObject('CATIA.Application')
for i in range(catiaObj.ActiveEditor.Selection.Count):
    print 'Selected Item %s: %s'%(i, catiaObj.ActiveEditor.Selection.Item(i + 1).Value.Name)

The next example throws a query (Weld0815*) to the VPM database, gets all relevant products and places all of them on a turntable view of the Silver Layer. This is very useful, if you want to compare different Products an one turntable view.

import win32com.client

# Search for every Product with name Weld0815*
catiaObj=win32com.client.GetActiveObject('CATIA.Application')
oSearchService = catiaObj.GetSessionService("PLMSearch")
oPLMSearches = oSearchService.Searches
oPLMSearch = oPLMSearches.Add()
oPLMSearch.Type = "PLMProductDS"
oPLMSearch.AddAttributeCriteria("PLM_ExternalID",  "Weld0815*")
oPLMSearch.search()

# Iterate over all found objects and put them into the turntable view
o3DShapeAsPLMEntities = oPLMSearch.EditedContent
print 'Found %s entries.'%o3DShapeAsPLMEntities.Count
for foundobj in o3DShapeAsPLMEntities:
    print 'Putting %s onto the table'%foundobj.Name
    oSelection = catiaObj.ActiveEditor.Selection
    oSelection.Add(foundobj)
    catiaObj.StartCommand("Turntable")

A batch script to convert CAD files with CATIA V5

import os, sys
import win32com.client


def convert(file, format):

    print '  Converting with CATIA V5'
    dirname, filename = os.path.split(file)
    basename, ext = os.path.splitext(filename)
    fileout=os.path.join(dirname, basename + '.' + format)
    try:
        CATIA = win32com.client.Dispatch('CATIA.Application')
    except:
        print 'Error connecting to CATIA! Either CATIA V5 is not installed or' \
        'you didn`t have registered CATIA V5 as a COM application.'
        print 'You can do this with:'
        print '   >> c:\\...\\Dassault Systemes\\intel_a\\code\\bin\\CNEXT.exe /regserver'
        sys.exit()
    CATIA.DisplayFileAlerts = False
    Doc = CATIA.Documents.Open(os.path.abspath(file))
    try:
        Doc.ExportData(fileout, format)
    except:
        print 'Could not convert file %s.'%file
    finally:
        Doc.Close()
        CATIA.Quit()
    print 'done'
    return fileout

if __name__ == "__main__":
    if len(sys.argv)==1:
        print 'Usage: v5batcher.py [filename] [format]'
    else:
        convert(sys.argv[1], sys.argv[2])


Autocad Automation

This example comes from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440493. It searches the ModelSpace collection for text objects. Once found it casts them and alter one of the text specific properties. To test this code AutoCAD must be started with a blank file open add at least one dtext object with ‘Spam’ as its value:

import win32com.client
acad = win32com.client.Dispatch("AutoCAD.Application")

doc = acad.ActiveDocument   # Document object
ms = doc.ModelSpace         # Modelspace "collection"
count = ms.Count            # Number of items in modelspace

for i in range(count):
    item = ms.Item(i)
    if 'text' in item.ObjectName.lower(): # Text objects are AcDbText
        # once we know what it is we can cast it
        text = win32com.client.CastTo(item, "IAcadText") 
        if text.TextString == "Spam":
            text.TextString = "Maps"
            text.Update()

Convert a 3D model with SolidWorks to 3DXML

An example how to convert a SolidWorks part to 3DXML:

import win32com.client

app=win32com.client.Dispatch("SldWorks.Application")
doc=app.OpenDoc("c:\\Testpart.SLDPRT", 1)
doc.SaveAs2("c:\\Testpart.3dxml", 0, True, False)

Change all xrefs in Autocad Drawings

This recipe (from Activestate) for Autodesk Autocad is a script which asks for a base directory and then changes all xrefs in all drawings in all subdirectories so that they use relative paths. To use it just copy it somewhere in your target directory structure and run.

# Relative-refs.pyw
"""A short python script for repathing xrefs in Autocad."""

import win32com.client,os, os.path, tkFileDialog
from Tkinter import *
from tkMessageBox import askokcancel
from time import sleep

# Get a COM object for Autocad
acad = win32com.client.Dispatch("AutoCAD.Application")

def repath(filename):
    print 'Repathing %s...' %filename
    doc = acad.Documents.Open(filename)
    
    blocks = doc.Database.Blocks # Internally xrefs are just blocks!
    xrefs = [item for item in blocks if item.IsXRef]
    
    if xrefs:
        for xref in xrefs:
            old_path = xref.Path
            new_path = os.path.join('..\\x-ref\\',os.path.basename(old_path))
            xref.Path = new_path
            print 'Old path name was %s, new path name is %s.\n' %(old_path, new_path)
    try:
        doc.Close(True) # Close and save
    except: # Something when wrong,
        doc.Close(False) # close then report it
        raise
    
class Logger:
    """A filelike object that prints its input on the screen."""
    
    def __init__(self, logfile=None):
        """Takes one argument, a file like object for logging."""
        print 'Starting logger...'
        if not logfile:
            self.logfile = open('relative-refs.log','w')
        else:
            self.logfile = logfile
        sys.stderr = self                 # Super cheap logging facility...
        sys.stdout = self                 # Just redirect output to a file.
        print 'Logger running...'
    
    def write(self, line):
        sys.__stdout__.write(line)
        self.logfile.write(line)
    
    def close(self):
        """The close method restores stdout and stderr to normal."""
        self.logfile.close()
        sys.stderr = sys.__stderr__
        sys.stdout = sys.__stdout__

class Tktextfile:
    """A file like interface to the Tk text widget."""
    
    def __init__(self, root):
        """Create a scrollable text widget to be written to."""
        self.root = root
        self.text = Text(root,width=40,height=20)
        self.text.pack(side=LEFT, expand=True, fill=BOTH)
        scrollbar = Scrollbar(root)
        scrollbar.pack(side=RIGHT,fill=Y)
        self.text.configure(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
        self.text.focus()
    
    def write(self, line):
        """Write method for file like widget."""
        self.text.insert(INSERT, line)
        self.text.see(END)
    
    def close(self):
        """Fake close method."""
        pass

if __name__ == '__main__':
    if acad.Visible:
        acad.Visible = False
    root = Tk()
    text = Tktextfile(root)
    logger = Logger(text)
    dir = tkFileDialog.askdirectory()

    answer = askokcancel('RePath','Re path all dwg files in ' + dir + '?')
    
    if answer:
        for dirpath, subdirs, files in os.walk(dir):
            for name in files:
                ext = name.split('.')[-1] or ''
                # We want dwg files which are not in the x-ref directory
                if ext.lower() == 'dwg' and 'x-ref' not in dirpath.lower():
                    drawing = os.path.join(dirpath, name)
                    try:
                        repath(drawing)
                    except:
                        print 'Unable to repath drawing %s!' %drawing
                root.update()
    acad.Visible = True

There is also another example on Activestate, which casts Python objects as the correct Autocad type via win32com.client.CastTo(item)

Automated generation of a simplified drive shaft

This script creates a new CATPart including parameters, design table, rules and checks (Knowledge Advisor).

The script runs with CATIA V5 Release R15 (R14 needs minor changes in code). It supports user interface languages english and german. The code is well commented, but comments are all in german. For some more informations, look at the short documentation (german).

import win32com.client  #Modul für COM-Client
import sys, os  #Für File-Handling
import win32gui #Für MessageBox

CATIA = win32com.client.Dispatch("CATIA.Application")


#Daten für Konstruktionstabelle 'Passfeder DIN 6885'
dmin=[8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10.,
      10., 10., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 17., 17., 17., 17., 17.,
      17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22.,
      22., 22., 22., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 30., 38., 38., 38., 38.,
      38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44.,
      44., 44., 44., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50., 50., 58., 58., 58., 58., 58., 58.,
      58., 58., 58., 58., 58., 58., 58., 65., 65., 65., 65., 65., 65., 65., 65., 65., 65., 65., 65., 65., 75., 75.,
      75., 75., 75., 75., 75., 75., 75., 75., 75., 75., 75., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85.,
      85., 85., 95., 95., 95., 95., 95., 95., 95., 95., 95., 95., 95., 95., 95., 110., 110., 110., 110., 110., 110.,
      110., 110., 110., 110., 110., 110., 110., 130., 130., 130., 130., 130., 130., 130., 130., 130., 130., 130., 130.,
      130.]
dmax=[10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 12., 12., 12., 12., 12., 12., 12., 12., 12.,
      12., 12., 12., 12., 12., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 17., 22., 22.,
      22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 30., 30., 30., 30., 30., 30., 30., 30., 30.,
      30., 30., 30., 30., 30., 30., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 38., 44.,
      44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 44., 50., 50., 50., 50., 50., 50., 50., 50.,
      50., 50., 50., 50., 50., 50., 58., 58., 58., 58., 58., 58., 58., 58., 58., 58., 58., 58., 58., 65., 65., 65.,
      65., 65., 65., 65., 65., 65., 65., 65., 65., 65., 75., 75., 75., 75., 75., 75., 75., 75., 75., 75., 75., 75.,
      75., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85., 85., 95., 95., 95., 95., 95., 95., 95., 95.,
      95., 95., 95., 95., 95., 110., 110., 110., 110., 110., 110., 110., 110., 110., 110., 110., 110., 110., 130.,
      130., 130., 130., 130., 130., 130., 130., 130., 130., 130., 130., 130., 150., 150., 150., 150., 150., 150.,
      150., 150., 150., 150., 150., 150., 150.]
b=[3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 5., 5.,
   5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 8.,
   8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 8., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 10.,
   10., 10., 10., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 14., 14., 14., 14., 14.,
   14., 14., 14., 14., 14., 14., 14., 14., 14., 16., 16., 16., 16., 16., 16., 16., 16., 16., 16., 16., 16., 16., 18.,
   18., 18., 18., 18., 18., 18., 18., 18., 18., 18., 18., 18., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20., 20.,
   20., 20., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 22., 25., 25., 25., 25., 25., 25., 25., 25.,
   25., 25., 25., 25., 25., 28., 28., 28., 28., 28., 28., 28., 28., 28., 28., 28., 28., 28., 32., 32., 32., 32., 32.,
   32., 32., 32., 32., 32., 32., 32., 32., 36., 36., 36., 36., 36., 36., 36., 36., 36., 36., 36., 36., 36.]
t=[1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
   2.5, 2.5, 2.5, 2.5, 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5,
   3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 4., 5., 5., 5., 5.,
   5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.5, 5.5,
   5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 6., 7.,
   7., 7., 7., 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 9.,
   9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 9., 10., 10., 10.,
   10., 10., 10., 10., 10., 10., 10., 10., 10., 10., 11., 11., 11., 11., 11., 11., 11., 11., 11., 11., 11., 11., 11.,
   12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12., 12.]
l=[6., 8., 10., 12., 14., 16., 18., 20., 22., 25., 28., 32., 36., 8., 10., 12., 14., 16., 18., 20., 22., 25., 28., 32.,
   36., 40., 45., 10., 12., 14., 16., 18., 20., 22., 25., 28., 32., 36., 40., 45., 50., 56., 14., 16., 18., 20., 22.,
   25., 28., 32., 36., 40., 45., 50., 56., 63., 70., 18., 20., 22., 25., 28., 32., 36., 40., 45., 50., 56., 63., 70.,
   80., 90., 22., 25., 28., 32., 36., 40., 45., 50., 56., 63., 70., 80., 90., 100., 110., 28., 32., 36., 40., 45., 50.,
   56., 63., 70., 80., 90., 100., 110., 125., 140., 36., 40., 45., 50., 56., 63., 70., 80., 90., 100., 110., 125.,
   140., 160., 45., 50., 56., 63., 70., 80., 90., 100., 110., 125., 140., 160., 180., 50., 56., 63., 70., 80., 90.,
   100., 110., 125., 140., 160., 180., 200., 56., 63., 70., 80., 90., 100., 110., 125., 140., 160., 180., 200., 220.,
   63., 70., 80., 90., 100., 110., 125., 140., 160., 180., 200., 220., 250., 70., 80., 90., 100., 110., 125., 140.,
   160., 180., 200., 220., 250., 280., 80., 90., 100., 110., 125., 140., 160., 180., 200., 220., 250., 280., 320., 90.,
   100., 110., 125., 140., 160., 180., 200., 220., 250., 280., 320., 360., 100., 110., 125., 140., 160., 180., 200.,
   220., 250., 280., 320., 360., 400.]

#Koordinaten für 2D-Geometrie, Welle + Passfedernut
# 0-7 Welle , 8-13 Passfedernut
x=[0.,0.,60.,60.,150.,150.,190.,190.,75.,75.,75.,125.,125.,125.]
y=[0.,15.,15.,25.,25.,18.,18.,0.,-7.,0.,7.,7.,0.,-7.]

PI=3.141592658

#Konstruktionstabelle 'Passfeder' erstellen
file=open("Passfeder.txt", "w")
file.write("dmin(mm)\tdmax(mm)\tbreite(mm)\ttiefe(mm)\tlaenge(mm)\n")
for i in range(len(dmin)):
    file.write(str(dmin[i])+"\t"+str(dmax[i])+"\t"+str(b[i])+"\t"+str(t[i])+"\t"+str(l[i])+"\n")
file.close()
Path=os.getcwd()                #Aktuellen Dateipfad speichern
FullPath=Path+"\Passfeder.txt"  #Pfad mit Dateinamen für Übergabe an CATIA

# Funktion zur Anpassung der Befehle an Umgebungssprache von CATIA (deutsch/englisch)
# Übergeben wird der im Quellcode verwendete englische Befehl
def trans(Command):
    "Übersetzt sprachspezifische Befehle für deutsche und englische Benutzerumgebung."
    translation={'Sketch':'Skizze','Exit workbench':'Umgebung verlassen','Sketch':'Skizze','Update':'Aktualisieren',
                 'AbsoluteAxis':'Absolute Achse',
         'HDirection':'H-Richtung','VDirection':'V-Richtung','PartBody':u'Hauptkörper','Shaft':'Welle','Length':u'Länge'}
    if language=="Englisch":
        result=Command  #Keine Änderung
    else:               #Deutsch
        result=translation[(Command)] #Deutschen Befehl zurückgeben
    return result

#CATIA ausblenden, Performancesteigerung, 'Kosmetik'
CATIA.Visible = False

# Neues CATPart erstellen
MyNewDoc=CATIA.Documents.Add("Part")    #"Part"=CATPart, "Product"=CATProduct
MyDoc=CATIA.ActiveDocument              #Aktives CATIA-Dokument
MyPart=MyDoc.Part                       #CATPart vom aktiven Dokument
MyBodies=MyPart.Bodies                  #MyBodies=Listenobjekt aller Körper
MyBody=MyBodies.Item(1) #Körper deklarieren (1)=Hauptkörper bzw. PartBody, (2)=nächster Körper im Baum

# Bei Eingabe von Namen, auf vorhandenen Namen prüfen und ggf. korrekten Indize vergeben 
tempname = raw_input("Name für neues\t CATPart: \n(leer = Standardname)")
num=CATIA.ActiveDocument.GetItem(MyNewDoc)  #index des neu geöffneten Parts
if len(tempname)<>0:                        #Eigenen Namen vergeben
    counter=1
    check=0
    newname=tempname
    while check0:                 #Check auf Namensgleichheit für alle offenen Dokumente durchlaufen
                    newname=tempname        #Namen übernehmen
                check=0                     #Durchlaufcheck reset
                counter=counter+1           #Zähler inkrementieren (MeinPart & MeinPart_1 vorhanden --> Zähler auf 2)
                newname=tempame+"_"+str(counter)
        check=check+1                       #Durchlaufcheck inkrementieren
    num.PartNumber=newname                  #Eigenen Namen an neues Part vergeben
else:                                       #Keine Eingabe --> Standardname vergeben
    newname = num.PartNumber                #Standardname in newname speichern

#Umgebungssprache feststellen (s. Funktion trans)
if MyBody.Name=="PartBody":         #Einfache (Einzige?) Möglichkeit festzustellen unter welcher Sprache CATIA läuft
    language="Englisch"
elif MyBody.Name==u"Hauptkörper":   #u".."= unicode-String (sonst keine Umlaute)
    language="Deutsch"
else:   #Fehlermeldung ausgeben, da Sprache nicht unterstützt wird
    print"Benutzersprache von CATIA wird nicht unterstützt, bitte auf Englisch oder Deutsch einstellen"
    win32gui.MessageBox(0, "Die gewählte Umgebungssprache von CATIA wird nicht unterstützt"+chr(13)+
                        "Bitte auf Deutsch oder Englisch einstellen", "Programmabbruch", 16)
    CATIA.Visible = True    #CATIA wieder einblenden
    sys.exit()              #Programm beenden    
    
#Sketcher öffnen
MySketches=MyBody.Sketches                  #Listenobjekt aller Skizzen
MyOriginElements=MyPart.OriginElements      #Ursprungselemente deklarieren (Achsen,Koord.Urspr.)
MyReference=MyOriginElements.PlaneXY        #Referenz der XY-Ebene erzeugen
MySketch=MySketches.Add(MyReference)        #Skizze auf XY-Ebene erzeugen
MySel=MyDoc.Selection                       #Objekt MySel der Klasse Selection erzeugen (Auswahl)
MySel.Add(MySketch)                         #XY-Ebene zur Auswahl hinzufügen (entspricht dem anklicken der Ebene)
CATIA.StartCommand(trans('Sketch'))         #Sketcher Workbench starten
KSS=[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0]   #[1-3] = Koord.Ursprung, [4-6] und [7-9] Vektoren der Achsrichtungen
MySketch.SetAbsoluteAxisData(KSS)           #Koordinatensystem zuweisen

#
#2D Geometrie Welle erzeugen
#
MySketch.OpenEdition                        #Skizze "intern" für Bearbeitung öffnen (läuft auch ohne!?)
MyGeo1 = MySketch.GeometricElements         #Achsen deklarieren für späteren Bezug durch Constraints
Axis = MyGeo1.Item(trans("AbsoluteAxis"))
AxisH = Axis.GetItem(trans("HDirection"))
AxisV = Axis.GetItem(trans("VDirection"))
factory2D1 = MySketch.Factory2D             #Klasse Factory2D stellt Methoden zur Definition von Geometrie bereit
#Punkte Welle
PW0 = factory2D1.CreatePoint(x[0],y[0])     #Punkte für Skizzengeometrie der Welle erzeugen
PW1 = factory2D1.CreatePoint(x[1],y[1])
PW2 = factory2D1.CreatePoint(x[2],y[2])
PW3 = factory2D1.CreatePoint(x[3],y[3])
PW4 = factory2D1.CreatePoint(x[4],y[4])
PW5 = factory2D1.CreatePoint(x[5],y[5])
PW6 = factory2D1.CreatePoint(x[6],y[6])
PW7 = factory2D1.CreatePoint(x[7],y[7])
#Punkte Achse
PA0 = factory2D1.CreatePoint(x[0],y[0]) 
PA1 = factory2D1.CreatePoint(x[7],y[7])
#Linien Welle
LW1 = factory2D1.CreateLine(x[0], y[0], x[1], y[1]) #Linien erzeugen
LW1.StartPoint = PW0                                #Start- und Ende der Linie mit den erzeugten Punkten verbinden
LW1.EndPoint = PW1
LW2 = factory2D1.CreateLine(x[1], y[1], x[2], y[2])
LW2.StartPoint = PW1
LW2.EndPoint = PW2
LW3 = factory2D1.CreateLine(x[2], y[2], x[3], y[3])
LW3.StartPoint = PW2
LW3.EndPoint = PW3
LW4 = factory2D1.CreateLine(x[3], y[3], x[4], y[4])
LW4.StartPoint = PW3
LW4.EndPoint = PW4
LW5 = factory2D1.CreateLine(x[4], y[4], x[5], y[5])
LW5.StartPoint = PW4
LW5.EndPoint = PW5
LW6 = factory2D1.CreateLine(x[5], y[5], x[6], y[6])
LW6.StartPoint = PW5
LW6.EndPoint = PW6
LW7 = factory2D1.CreateLine(x[6], y[6], x[7], y[7])
LW7.StartPoint = PW6
LW7.EndPoint = PW7
#Linie Achse
LA = factory2D1.CreateLine(x[0], y[0], x[7], y[7])
LA.StartPoint = PA0
LA.EndPoint = PA1
MySketch.CenterLine = LA                        #Linie als Achse definieren

#Constraints
#Constraints können nur an Referenzen der Objekte zugewiesen werden
MyCons=MySketch.Constraints                     #Listenelement Constraints
RLA = MyPart.CreateReferenceFromObject(LA)      #Referenz der Achse
CLA = MyCons.AddMonoEltCst(10,RLA)              #..Mono.. = verarbeitet 1 Referenz, 10 = Horizontal
#Constraints Horizontal/Vertikal
RLW1 = MyPart.CreateReferenceFromObject(LW1)
CLW1 = MyCons.AddMonoEltCst(13,RLW1)            #13 = Vertikal
RLW2 = MyPart.CreateReferenceFromObject(LW2)
CLW2 = MyCons.AddMonoEltCst(10,RLW2) 
RLW3 = MyPart.CreateReferenceFromObject(LW3)
CLW3 = MyCons.AddMonoEltCst(13,RLW3) 
RLW4 = MyPart.CreateReferenceFromObject(LW4)
CLW4 = MyCons.AddMonoEltCst(10,RLW4)
RLW5 = MyPart.CreateReferenceFromObject(LW5)
CLW5 = MyCons.AddMonoEltCst(13,RLW5) 
RLW6 = MyPart.CreateReferenceFromObject(LW6)
CLW6 = MyCons.AddMonoEltCst(10,RLW6)
RLW7 = MyPart.CreateReferenceFromObject(LW7)
CLW7 = MyCons.AddMonoEltCst(13,RLW7)
#Constraints Koinzidenz Punkte/Achse
RPW0 = MyPart.CreateReferenceFromObject(PW0)
CPW0_LA0 = MyCons.AddBiEltCst(2,RPW0,RLA)       #..Bi.. = 2 Referenzen, 2 = Koinzidenz
RPW7 = MyPart.CreateReferenceFromObject(PW7)
CPW7_LA0 = MyCons.AddBiEltCst(2,RPW7,RLA)
#Constraints Dimension Durchmesser
CDLW2_rad = MyCons.AddBiEltCst(26, RLA, RLW2)   #26 = Bemaßung Radius
CDLW2_rad.Mode = 0                              #Mode 0 = Driving Dimension, Mode 1= Driven Dimension
DLW2_rad = CDLW2_rad.Dimension
DLW2_rad.Value = y[2]
CDLW4_rad = MyCons.AddBiEltCst(26, RLA, RLW4)
CDLW4_rad.Mode = 0
DLW4_rad = CDLW4_rad.Dimension
DLW4_rad.Value = y[4]
CDLW6_rad = MyCons.AddBiEltCst(26, RLA, RLW6)
CDLW6_rad.Mode = 0
DLW6_rad = CDLW6_rad.Dimension
DLW6_rad.Value = y[6]
#Constraints Dimension Längen
CDLW2_len = MyCons.AddMonoEltCst(5, RLW2)       #5 = Bemaßung Länge
CDLW2_len.Mode = 0
DLW2_len = CDLW2_len.Dimension
DLW2_len.Value=abs(x[1]-x[2])
CDLW4_len = MyCons.AddMonoEltCst(5, RLW4)
CDLW4_len.Mode = 0
DLW4_len = CDLW4_len.Dimension
DLW4_len.Value=abs(x[3]-x[4])
CDLW6_len = MyCons.AddMonoEltCst(5, RLW6)
CDLW6_len.Mode = 0
DLW6_len = CDLW6_len.Dimension
DLW6_len.Value=abs(x[5]-x[6])
#Constraints Position der Skizze an KS fixieren
RAxisV = MyPart.CreateReferenceFromObject(AxisV)        #KS-Achse-Vertikal
CLW1_AxisV = MyCons.AddBiEltCst(2,RLW1,RAxisV)          #Constr. Welle links Koinzident mit senkrechter KS-Achse
RAxisH = MyPart.CreateReferenceFromObject(AxisH)        #KS-Achse-Horiz.
CLA_AxisH = MyCons.AddBiEltCst(2,RLA,RAxisH)            #Constr. WellenAchse Koinzident zur waagerechten KS-Achse

MySketch.CloseEdition                                   #Skizze "intern" schließen
CATIA.StartCommand(trans("Exit workbench"))             #Entspr. Klick auf "Umgebung verlassen"


#Körper durch Rotation
MyShapeFactory=MyPart.ShapeFactory
MyShape=MyShapeFactory.AddNewShaft(MySketch)            #'Welle' hinzufügen auf Skizzenbasis MySketch
MyParas=MyPart.Parameters                       
PShaft1=MyParas.Item(newname+"\\"+trans("PartBody")+"\\"+trans("Shaft")+".1\ThickThin1")    #Parameter1 für Welle
PShaft1.Value=1.                                                                            #Wert zuweisen
PShaft2=MyParas.Item(newname+"\\"+trans("PartBody")+"\\"+trans("Shaft")+".1\ThickThin2")    #Parameter2 für Welle
PShaft2.Value=0.                                                                            #Wert zuweisen

CATIA.StartCommand(trans("Update"))     #Aktualisieren
MySel.Clear()                           #Auswahl aufheben (=demarkieren)
#
#Sketch.2 erstellen für Passfeder
#
MyPart.InWorkObject=MyBody              #Objekt in Bearbeitung definieren
MySketch2=MySketches.Add(MyReference)   #-> Siehe MySketch oben
MySel=MyDoc.Selection
MySel.Add(MySketch2)
CATIA.StartCommand(trans("Sketch"))
MySel.Clear()
factory2D1 = MySketch2.Factory2D
MyCons=MySketch2.Constraints
MySketch2.OpenEdition()
#
# 2D Geometrie Passfedernut erzeugen
#
#Punkte
PP0 = factory2D1.CreatePoint(x[8], y[8])    #Kreis Anfangs-,Mittel-, und Endpunkte für Langlochgeometrie
PP1 = factory2D1.CreatePoint(x[9], y[9])
PP2 = factory2D1.CreatePoint(x[10], y[10])
PP3 = factory2D1.CreatePoint(x[11], y[11])
PP4 = factory2D1.CreatePoint(x[12], y[12])
PP5 = factory2D1.CreatePoint(x[13], y[13])
#Radius1 (Links)
RadP1 = factory2D1.CreateCircle(x[8], y[9], y[10]-y[9], PI/2.,PI*1.5)   #Kreisbogen zeichnen
RadP1.CenterPoint = PP1
RadP1.StartPoint = PP2
RadP1.EndPoint = PP0
#Linie1 (Oben)
LP1 = factory2D1.CreateLine(x[10],y[10],x[11],y[11])
LP1.StartPoint = PP2
LP1.EndPoint = PP3
#Radius2 (Rechts)
RadP2 = factory2D1.CreateCircle(x[12],y[12], y[11]-y[12], PI*1.5, PI*2.5)
RadP2.CenterPoint = PP4
RadP2.StartPoint = PP5
RadP2.EndPoint = PP3
#Linie2 (Unten)
LP2 = factory2D1.CreateLine(x[13],y[13],x[8],y[8])
LP2.StartPoint = PP5
LP2.EndPoint = PP0

#Constraints Passfedernut
MyGeo2 = MySketch2.GeometricElements
Axis2 = MyGeo2.Item(trans("AbsoluteAxis"))
AxisH2 = Axis2.GetItem(trans("HDirection"))
AxisV2 = Axis2.GetItem(trans("VDirection"))
#Linie 1 Horizontal (Unten)
RLP1 = MyPart.CreateReferenceFromObject(LP1)
CLP1 = MyCons.AddMonoEltCst(10, RLP1)
#Linie 2 Horizontal (Oben)
RLP2 = MyPart.CreateReferenceFromObject(LP2)
CLP2 = MyCons.AddMonoEltCst(10, RLP2)
#Linie1+Radius1 Tangential (Links Unten)
RRadP1 = MyPart.CreateReferenceFromObject(RadP1)
CRadP1_LP1 = MyCons.AddBiEltCst(4,RLP1,RRadP1)          #Constraint 4 = Tangential
#Linie2+Radius1 Tangential (Links Oben)
CRadP1_LP2 = MyCons.AddBiEltCst(4,RLP2,RRadP1)
#Linie1+Radius2 Tangential (Rechts Unten)
RRadP2 = MyPart.CreateReferenceFromObject(RadP2)
CRadP2_LP1 = MyCons.AddBiEltCst(4,RLP1,RRadP2)
#Linie2+Radius2 Tangential (Rechts Oben)
CRadP2_LP2 = MyCons.AddBiEltCst(4,RLP2,RRadP2)
#MittellPunkt Nut-Radius auf WellenAchse legen
RPP1 = MyPart.CreateReferenceFromObject(PP1)
RAxisH2 = MyPart.CreateReferenceFromObject(AxisH2)
CPP1_AxisH2 = MyCons.AddBiEltCst(2,RPP1,RAxisH2)
#Langloch position auf LängsAchseWelle
RAxisV2 = MyPart.CreateReferenceFromObject(AxisV2)
CDPP1_AxisV2 = MyCons.AddBiEltCst(1, RAxisV2,RPP1)
CDPP1_AxisV2.Mode = 0
DPP1_AxisV2 = CDPP1_AxisV2.Dimension
DPP1_AxisV2.Value = 85.
#Langloch Breite
CDLP1_LP2 = MyCons.AddBiEltCst(1,RLP1, RLP2)
CDLP1_LP2.Mode = 0
DLP1_LP2 = CDLP1_LP2.Dimension
DLP1_LP2.Value = 10.
#Langloch Länge (Tragende Länge der Passfeder , MitteRadius-MitteRadius)
RPP4 = MyPart.CreateReferenceFromObject(PP4)
CDPP1_PP4 = MyCons.AddBiEltCst(1,RPP1, RPP4)
CDPP1_PP4.Mode = 0
DPP1_PP4 = CDPP1_PP4.Dimension
DPP1_PP4.Value = 40.

MySketch2.CloseEdition()                        #Skizzieren abschließen
CATIA.StartCommand(trans("Exit workbench"))     #Skizziermodus verlassen

#
#Passfedernut (Tasche) erzeugen
#
MyPocket=MyShapeFactory.AddNewPocket(MySketch2, 10.)    #Tasche auf Skizzenbasis MySketch2
limit1 = MyPocket.FirstLimit                            # 1. Begrenzung
limit1.LimitMode = 2                                    #catUpToLastLimit (Bis zum letzten)
MyPocket.DirectionOrientation = 0                       #catRegularOrientation (Reguläre Orientierung)
limit2 = MyPocket.SecondLimit
length1 = limit2.Dimension                              # 2. Begrenzung durch Bemaßung
length1.Value = -25.
CATIA.StartCommand(trans("Update"))

#
#Fasen und Radien
#
MyPart.InWorkObject = MyBody
# 2 identische Fasen über LeerReferenz
EmptyRef = MyPart.CreateReferenceFromName("")                       #Leer-Referenz erzeugen
Chamfer1 = MyPart.ShapeFactory.AddNewChamfer(EmptyRef,0,1,0,2.,45.) #Fase definieren, Parameter s. V5Automation
Pocket = MyPart.MainBody.Shapes.Item("Shaft.1")
Face4 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;4)));None:())"         #Flächen deklarieren, die an Fasenkante liegen
Face5 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;5)));None:())"
Face6 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;6)));None:())"
Endung1 = ";None:(Limits1:();Limits2:()))"                          #Hilfsvar.
Endung2 = ";WithTemporaryBody;WithoutBuildError;WithSelectingFeatureSupport)"   #Hilfsvar.
Edge45 = "Edge:("+ Face4 + ";" + Face5 + Endung1                    #Kante zwischen Flächen 4/5 deklarieren
Edge56 = "Edge:("+ Face5 + ";" + Face6 + Endung1                    #Kante zw. Fl. 5/6
RemEdge45 = "REdge:(" + Edge45 + Endung2                            #RemEdge = Removeable, d.h. Element ist nach OP 
RemEdge56 = "REdge:(" + Edge56 + Endung2                            #                           nicht mehr vorhanden
RRemEdge45 = MyPart.CreateReferenceFromBRepName(RemEdge45, Pocket)  #BRep-Referenz von 1.Kante 
Chamfer1.AddElementToChamfer(RRemEdge45)                            #Zur Auswahl hinzufügen
RRemEdge56 = MyPart.CreateReferenceFromBRepName(RemEdge56, Pocket)  #2.Kante
Chamfer1.AddElementToChamfer(RRemEdge56)
Fase_Nabe=Chamfer1.Length1
Chamfer1.Length1.Rename("Fase_Nabe")                                #Parameter umbenennen

#Fase an Wellenzapfen 1                                             #Einzelne Fase ohne Leer-Referenz
Face7 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;7)));None:())"
Face8 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;8)));None:())"
Edge78 = "Edge:("+ Face7 + ";" + Face8 + Endung1
RemEdge78 = "REdge:(" + Edge78 + Endung2
RRemEdge78 = MyPart.CreateReferenceFromBRepName(RemEdge78, Pocket)
Chamfer78 = MyPart.ShapeFactory.AddNewChamfer(RRemEdge78,0,1,0,2,45)
Fase_Zapfen_1=Chamfer78.Length1
Chamfer78.Length1.Rename("Fase_Zapfen_1")

#Fase an Wellenzapfen 2
Face1 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;1)));None:())"
Face3 = "Face:(Brp:(Shaft.1;0:(Brp:(Sketch.1;3)));None:())"
Edge13 = "Edge:("+ Face1 + ";" + Face3 + Endung1
RemEdge13 = "REdge:(" + Edge13 + Endung2
RRemEdge13 = MyPart.CreateReferenceFromBRepName(RemEdge13, Pocket)
Chamfer13 = MyPart.ShapeFactory.AddNewChamfer(RRemEdge13,0,1,0,2,45)
Fase_Zapfen_2=Chamfer13.Length1
Chamfer13.Length1.Rename("Fase_Zapfen_2")

#InnenRadius Zapfen 1
Edge67 = "Edge:("+ Face6 + ";" + Face7 + Endung1
RemEdge67 = "REdge:(" + Edge67 + Endung2
RRemEdge67 = MyPart.CreateReferenceFromBRepName(RemEdge67, Pocket)
Fillet67 = MyPart.ShapeFactory.AddNewEdgeFilletWithConstantRadius(RRemEdge67,1,1.)
Radius_Zapfen_1=Fillet67.Radius
Fillet67.Radius.Rename("Radius_Zapfen_1")

#InnenRadius Zapfen 2
Edge34 = "Edge:("+ Face3 + ";" + Face4 + Endung1
RemEdge34 = "REdge:(" + Edge34 + Endung2
RRemEdge34 = MyPart.CreateReferenceFromBRepName(RemEdge34, Pocket)
Fillet34 = MyPart.ShapeFactory.AddNewEdgeFilletWithConstantRadius(RRemEdge34,1,1.)
Radius_Zapfen_2=Fillet34.Radius
Fillet34.Radius.Rename("Radius_Zapfen_2")

CATIA.StartCommand(trans("Update"))

#
#Parameter und Beziehungen
#
MyParas = CATIA.ActiveDocument.Part.Parameters
MyRels = MyPart.Relations
#Paras
DNabe = MyParas.CreateDimension ("Durchmesser_Nabe","Length",50.)   #Parameter erzeugen und Wert zuweisen
DNabe.RangeMax = 200
LNabe = MyParas.CreateDimension ("Laenge_Nabe","Length",90.)
LNabe.RangeMax=500                                                  #Parameterbegrenzung MAX
DZapfen1 = MyParas.CreateDimension ("Durchmesser_Zapfen_1","Length",30.)
DZapfen1.RangeMin = 8                                               #Parameterbegrenzung MIN
DZapfen1.RangeMax = 150
LZapfen1 = MyParas.CreateDimension ("Laenge_Zapfen_1","Length",60.)
LZapfen1.RangeMax = 200
DZapfen2 = MyParas.CreateDimension ("Durchmesser_Zapfen_2","Length",36.)
DZapfen2.RangeMin = 8
DZapfen2.RangeMax = 150
LZapfen2 = MyParas.CreateDimension ("Laenge_Zapfen_2","Length",40.)
LZapfen2.RangeMax = 200

#Parameter Konstruktionstabelle
dmin = MyParas.CreateDimension ("dmin","Length",60.)
dmin.Hidden = True                                                  #Parameter verstecken
dmax = MyParas.CreateDimension ("dmax","Length",60.)
dmax.Hidden = True
Nutbreite = MyParas.CreateDimension ("Nutbreite","Length",8.8)
Nutbreite.Hidden = True
Nuttiefe = MyParas.CreateDimension ("Nuttiefe","Length",8.8)
Nuttiefe.Hidden = True
Nutlaenge = MyParas.CreateDimension ("Nutlaenge","Length",40.)
Nutlaenge.Hidden = True

#Relations  , Verknüpfen der Parameter mit Bemaßung
Formel1 = MyRels.CreateFormula("Formel_1","Zapfenlänge 1",DLW2_len,"Laenge_Zapfen_1")
Formel1.Hidden=True                 
Formel2 = MyRels.CreateFormula("Formel_2","Zapfenlänge 2",DLW6_len,"Laenge_Zapfen_2")
Formel2.Hidden=True
Formel3 = MyRels.CreateFormula("Formel_3","Nabennlänge",DLW4_len,"Laenge_Nabe")
Formel3.Hidden=True
Formel4 = MyRels.CreateFormula("Formel_4","Durchmesser Zapfen 1",DLW2_rad,"Durchmesser_Zapfen_1/2.")
Formel4.Hidden=True
Formel5 = MyRels.CreateFormula("Formel_5","Durchmesser Zapfen 1",DLW6_rad,"Durchmesser_Zapfen_2/2.")
Formel5.Hidden=True
Formel6 = MyRels.CreateFormula("Formel_6","Durchmesser Nabe",DLW4_rad,"Durchmesser_Nabe/2.")
Formel6.Hidden=True
#Konstr.Tabelle
Formel7 = MyRels.CreateFormula("Formel_7","Breite Passfedernut",DLP1_LP2,"Nutbreite")
Formel7.Hidden=True
Formel8 = MyRels.CreateFormula("Formel_8","Tiefe Passfedernut",length1,"-Durchmesser_Nabe/2+Nuttiefe")
Formel8.Hidden=True
Formel9 = MyRels.CreateFormula("Formel_9","Länge Passfedernut",DPP1_PP4,"Nutlaenge-Nutbreite")
Formel9.Hidden=True
#Geometrie der Welle
Formel10 = MyRels.CreateFormula("Formel_10","Position Nut mittig auf Nabe",DPP1_AxisV2,
                                "(Laenge_Nabe-Nutlaenge+Nutbreite)/2+Laenge_Zapfen_1")
Formel10.Hidden=True
Formel11 = MyRels.CreateFormula("Formel_11","Fase = 1/20 des Durchmessers",Fase_Zapfen_1,"Durchmesser_Zapfen_1/20.")
Formel11.Hidden=True
Formel12 = MyRels.CreateFormula("Formel_12","Fase = 1/20 des Durchmessers",Fase_Zapfen_2,"Durchmesser_Zapfen_2/20.")
Formel12.Hidden=True
Formel13 = MyRels.CreateFormula("Formel_13","Fase = 1/20 des Durchmessers",Fase_Nabe,"Durchmesser_Nabe/20.")
Formel13.Hidden=True
Formel14 = MyRels.CreateFormula("Formel_14","Radius = Wellenabsatz/2 ",Radius_Zapfen_1,
                                "(Durchmesser_Nabe-(Durchmesser_Zapfen_1+2*Fase_Nabe))/8.")
Formel14.Hidden=True
Formel15 = MyRels.CreateFormula("Formel_15","Radius = Wellenabsatz/2",Radius_Zapfen_2,
                                "(Durchmesser_Nabe-(Durchmesser_Zapfen_2+2*Fase_Nabe))/8.")
Formel15.Hidden=True

#Regeln erzeugen, um Eingabe unsinniger Parameter zu unterbinden
Rule1 = MyRels.CreateProgram("Check Länge Nut-Nabe","", "" +chr(10)+ "if Laenge_Nabe < Nutlaenge+2*Fase_Nabe" +chr(10) + "Message (\"Passfedernut länger als Nabe ! | Mindestlänge Welle (Nabe) = # mm\" , (Nutlaenge+2*Fase_Nabe)*1000)" ) Rule1.Hidden=True Rule2 = MyRels.CreateProgram("Check Durchmesser Zapfen_1-Nabe","", "" +chr(10)+ "if Durchmesser_Zapfen_1 > ( Durchmesser_Nabe-(2*Fase_Nabe+Radius_Zapfen_1+1mm ))" +chr(10) +
"Message (\"Durchmesserverhältnis stimmt nicht!|Entweder Durchmesser_Nabe vergrößern |oder Durchmesser_Zapfen_1 verkleinern\")" )
Rule2.Hidden=True

Rule3 = MyRels.CreateProgram("Check Durchmesser Zapfen_2-Nabe","", "" +chr(10)+
"if Durchmesser_Zapfen_2 > ( Durchmesser_Nabe-(2*Fase_Nabe+Radius_Zapfen_2+1mm ))" +chr(10) +
"Message (\"Durchmesserverhältnis stimmt nicht!|Entweder Durchmesser_Nabe vergrößern |oder Durchmesser_Zapfen_2 verkleinern\")" )
Rule3.Hidden=True

Rule4 = MyRels.CreateProgram("Check Länge Zapfen_1","", "" +chr(10)+
"if Laenge_Zapfen_1 < ( Fase_Zapfen_1+Radius_Zapfen_1+1mm )" +chr(10) +"Message (\"Zapfen_1 zu kurz!\")" )
Rule4.Hidden=True

Rule5 = MyRels.CreateProgram("Check Länge Zapfen_2","", "" +chr(10)+
"if Laenge_Zapfen_2 < ( Fase_Zapfen_2+Radius_Zapfen_2+1mm )" +chr(10) +"Message (\"Zapfen_1 zu kurz!\")" ) Rule5.Hidden=True Rule6 = MyRels.CreateProgram("Check Durchmesser Nabe","", "" +chr(10)+ "if Durchmesser_Nabe > 150mm" +chr(10) +"Message (\"Für D>150mm ist in der Konstruktionstabelle keine Passfedernut nach DIN6885 hinterlegt!\")" )
Rule6.Hidden=True


#Werte Konstruktionstabelle zuweisen
MyTab=MyRels.CreateDesignTable ("Passfeder","Passfedernut nach DIN6885", True, FullPath)    #Pfad zur txt-Datei
MyTab.AddAssociation(dmin, "dmin")                                                      #Zuweisen der Werte an Parameter
MyTab.AddAssociation(dmax, "dmax")
MyTab.AddAssociation (Nutbreite, "breite")                                          
MyTab.AddAssociation (Nuttiefe, "tiefe")
MyTab.AddAssociation(Nutlaenge, "laenge")
MyTab.Configuration=106  

#Check erzeugen, Überprüft ob Größe der Passfedernut zum Durchmesser der Welle passt
check1 = MyRels.CreateCheck("DIN 6885 eingehalten", "", "Durchmesser_Nabe>dmin AND Durchmesser_Nabe<=dmax")
check1.Severity = 1     #1 = Silent, d.h. es wird kein Fenster geöffnet, Anzeige über 'Ampel'

CATIA.StartCommand(trans("Update"))
CATIA.Visible = True    #CATIA wieder einblenden

Print the Volume of a body from CATIA V5

try:
    import win32com.client
except: 
    print "Ooops Pywin32 needed !" 
app=win32com.client.Dispatch('CATIA.Application') 
doc=app.ActiveDocument.Product 
a=doc.Analyze.Volume 
print "The Volume is: ", a