= Python = == Prvi program == 1. Odpremo IDLE (Python GUI) in odtipkamo naslednjo vrstico {{{ #!python print "Hello, world!" }}} 2. Pred shranjevanjem v IDLE še nastavimo Options->Configure Idle->General->Sefault Source Encoding->UTF-8. 3. Shranimo datoteko z ukazom File->Save->hello.py 4. Poženemo skript z F5 ali Run->Run Module == Drugi program == Jezik nekoliko bolje predstavimo z drugim programom, ki vsebuje funkcijo in bere {{{ #!python # drugi program import math def ploscina(d): return math.pi*d**2/4 d = input("Vnesi premer kroga: ") print u"Ploščina kroga je %.2f" % ploscina(d) }}} = Osnove pythona = Python je skriptni jezik, pri katerem se stvari izvajajo ob tem, ko naleti interpreter na vrstico. Se pravi, da se vse ukaza, kot tudi upravljanje s spremenljivkami oz podatki izvaja dinamično. Pomembno tudi to, da vse prednosti in slabosti iz drugih jezikov nakako v Pythonu bolje rešene. Ena od pomembnih novosti je seveda zamikanje ukazov. Ker potem programi vsi izgledajo bolje in jih lažje beremo. Po nekih raziskava je bilo ugotovljeno, da program enkrat pišemo, beremo ga pa večkrat. In prav berljivost je pomembna! == Spremenljivke == Imena spremenljiv so poljubna. Python je občutljiv na velike in male črke. Sledimo dogovoru in priporočilom, kot je to v podobnih jezikih. Vse spremenljivke so nakako avtomatske. Torej so generirane ob prvi uporabi. Tako imamo lahko par različih (osnovnih) tipov kot so: 1. integer (int, short, cardinal)- cela števila - v dogovoru se izbirajo za kratka imena spremenljivk i, j, k, l, m, n 2. floating point (real, float, double) - plavajoča vejica ali realna ševila 3. niz znakov ali string 4. bool ali true/false označevanje, ki pa je prav zaprav integer 5. Kompleksna števila (Realni+Imaginarni''i'') Sedaj lahko sestavljamo osnovne tipe tu v sestavljene tipe, kot so na primer: 1. Array - vektor - matrika - list - seznam ne nujno istovrstnih osnovnih tipov 2. Slovarji (map) - dictionary - asociativni seznami 3. Terke (''tuple'') ali se seznami fiksnih velikosti, ki se uporabljajo za hranjenje različnih osnovnih tipov v enem skupku. 4. Strukture (razredi) Kateri tip se je ob prireditvi podal lahko preverimo z ukazom type(tip) == Operatorji == Operirajo s spremenljivkami. Vsak programski jezik ima nabor teh stvari in se ne razlikuje od novejših jezikov. Ima python prav nekaj ''lepih'' operatorev (npr tuple, +). Obstajajo seveda vsi normalni operatorji, +, -, *, /, //, % Okrajšani operatorji +=, -=, Primer: {{{ #!python # -*- coding: cp1250 -*- # komentar se prične z # in veja do konca vrstice i = 1 # celoštevilčna a = 1.2 # realno število t = "besedilo" # niz znakov t2 = 'ni nobene razlike' # razen v prirocnisti c = 1 + 2j # kompleksno # Operatorji na osnovnih tipih print i+1 print a+i print t+str(a) i, j = (1, 2) # skupek prireditev (tuple) i, j = j, i print i, j # Sestavljeni tipi b = [1, 2, 3] # seznam ali list print b[0] b.append(4) # dodamo element na koncu b[5]=5 # Matrike m = [1,2,3,4,5,6,7,8,9] # Vektor m lahko interpretiramo kot matriko s tem, da preračunavamo indeks i=1 j=2 print m[i*3+j] }}} Tuple ali terke se uporabljajo predvsem za sestavljanje podatkov. Najpogostejši primer je prenašanje rezultatov iz funkcij oziroma podprogramov. Skupek je običajno v okroglih oklepajih, ki pa se lahko tudi opustijo. == Kontrolni ukazi == * if * for * while * funkcije ali podprogrami Pomembno je, da za vsakim kontrolnim ukazom podamo dvopičje, ki pomeni, da se v naslednjih vrsticah pričakuje zamaknjen blok ukazov. {{{ #!python i = input("Stevilo zob:") if i < 5 : print "Premajhno stevilo zob" else: print "OK" }}} Stavek for je iterator. LE ta pa "iterira" po vseh elementih. Zato običajno nimamo podanega obsega, ki pa ga pridelamo z ukazom range(). {{{ #!python for i in range(10): i = i + 1 print i }}} Za prekintev zanke for uporabimo ukaz break. Ta ukaz takoj prekine vse nadaljnjne iteracije. Ukaz continue v zankah pa nadaljuje z naslednjim elementom. Funkcije oz. podprograme pišemo in uporabljamo praktično povsod. Začnejo se z ukazom def, sledi ime in argumenti, ter konča z : Telo funkcije je zamaknjeno. Vsaka funkcija vrača nek rezultat. Rezultate vračamo s skupkom (tuple) {{{ #!python def zamenjaj(i, j): return (j, i) i, j = 1, 2 i, j = zamenjaj (i, j) print i, j }}} == Predstavitev CAD-jedra Open CASCADE na primerih == === Pregled uporabljenih OCC knjižnic === {{{ #!python ## Importanje različnih knjižnic # Uporabniški vmesnik GUI from OCC.Display.SimpleGui import * # Matematična knjižnica import math # OpenCascade from OCC.gp import * #točke from OCC.BRepBuilderAPI import * #gradimo robove, segmente, mreže ... from OCC.BRepPrimAPI import * #izdelava osnovnih geometrijskih primitivov from OCC.BRepFilletAPI import * #izdelava zaokrožitev }}} Točnejša navodila, opis funkcij in knjižnic lahko dobimo v PythonOCC dokumentaciji. === Inicializacija zaslona in izdelava grafičnega vmesnika=== {{{ #!python # OCC.Display.SimpleGui.init_display() returns multiple # values which are assigned here display, start_display, add_menu, add_function_to_menu = \ init_display() draw_bottle() #kličemo CAD model, ki ga želimo prikazati na zaslonu start_display() }}} === Risanje točk v prostoru === Izdelava točk v prostoru je najosnovnejša operacija v OCC. {{{ #!python # Definiranje začetnih točk aPnt1 = gp_Pnt(-myWidth / 2. , 0 , 0) aPnt2 = gp_Pnt(-myWidth / 2. , -myThickness / 4. , 0) aPnt3 = gp_Pnt(0 , -myThickness / 2. , 0) aPnt4 = gp_Pnt(myWidth / 2. , -myThickness / 4. , 0) aPnt5 = gp_Pnt(myWidth / 2. , 0 , 0) }}} === Izdelava robnih elementov === V naslednjem koraku se iz začetnih točk izdela robove: {{{ #!python # Definiranje geometrije aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4) aSegment1 = GC_MakeSegment(aPnt1 , aPnt2) aSegment2 = GC_MakeSegment(aPnt4 , aPnt5) # Definiranje topologije aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value()) aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value()) aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value()) }}} === Povezovanje robnih elementov v mreže === Robne elemente se v nadaljevanju združi v mrežo. {{{ #!python # Izdelava mreže aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge()) }}} === Uporaba funkcij za izdelavo objektov v prostoru === {{{ #!python # Izdelava celotnega profila - mirror xAxis = gp_OX() aTrsf = gp_Trsf() aTrsf.SetMirror(xAxis) aBRepTrsf = BRepBuilderAPI_Transform(aWire.Shape() , aTrsf) aMirroredShape = aBRepTrsf.Shape() aMirroredWire = TopoDS_wire(aMirroredShape) mkWire = BRepBuilderAPI_MakeWire() mkWire.Add(aWire.Wire()) mkWire.Add(aMirroredWire) myWireProfile = mkWire.Wire() # Telo: Iz profila se izdela telo (Funkcija izvleka 3D) myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile) aPrismVec = gp_Vec(0 , 0 , myHeight) myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face() , aPrismVec) }}} === Risanje geometrijskih primitivov === V OCC že obstajajo funkcije za izdelavo geometrijskih primitivov (kocka, valj,...), kar je prikazano na spodnjem primeru. {{{ #!python from OCC.Display.SimpleGui import * from OCC.BRepPrimAPI import * display, start_display, add_menu, add_function_to_menu = init_display() my_box = BRepPrimAPI_MakeBox(10.,20.,30.).Shape() # ali my_cylinder = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , myNeckHeight), kjer so spremenljivke že preddefinirane display.DisplayShape(my_box) # ali display.DisplayShape(my_cylinder) start_display() }}} === Izdelava primera Bottle z uporabo programskega jezika Python in knjižnice OCC === Naslednji primer prikazuje izdelavo primera BottleCAD. Podrobnejši razdelek posameznih delov programske kode dobimo na [[http://trac.lecad.si/vaje/wiki/OpenCascade|MakeBottleCAD(C++)]]. {{{ #!python ##Copyright 2011 Simon Kulovec (simon.kulovec@lecad.si) ##Example: MakeCADBottle ##This file is part of pythonOCC. ## Importanje različnih knjižnic # Uporabniški vmesnik GUI from OCC.Display.SimpleGui import * # OpenCascade from OCC.gp import * from OCC.TopoDS import * from OCC.GC import * from OCC.BRepBuilderAPI import * from OCC.BRepPrimAPI import * from OCC.BRepFilletAPI import * from OCC.BRepAlgoAPI import * from OCC.Utils.Topology import * from OCC.Geom import * from OCC.Geom2d import * from OCC.GCE2d import * from OCC.BRep import * from OCC.BRepLib import * from OCC.BRepOffsetAPI import * from OCC.TopTools import * from OCC.TopAbs import * from OCC.TopExp import * import math def show_bottle(aRes): display.EraseAll() print dir(display) display.DisplayShape(aRes) def define_points(myWidth, myThickness, myHeight): #Definiranje začetnih točk aPnt1 = gp_Pnt(-myWidth / 2. , 0 , 0) aPnt2 = gp_Pnt(-myWidth / 2. , -myThickness / 4. , 0) aPnt3 = gp_Pnt(0 , -myThickness / 2. , 0) aPnt4 = gp_Pnt(myWidth / 2. , -myThickness / 4. , 0) aPnt5 = gp_Pnt(myWidth / 2. , 0 , 0) #Definiranje geometrije aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4) aSegment1 = GC_MakeSegment(aPnt1 , aPnt2) aSegment2 = GC_MakeSegment(aPnt4 , aPnt5) #Definiranje topologije aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value()) aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value()) aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value()) aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge()) #Izdelava celotnega profila - mirror xAxis = gp_OX() aTrsf = gp_Trsf() aTrsf.SetMirror(xAxis) aBRepTrsf = BRepBuilderAPI_Transform(aWire.Shape() , aTrsf) aMirroredShape = aBRepTrsf.Shape() aMirroredWire = TopoDS_wire(aMirroredShape) mkWire = BRepBuilderAPI_MakeWire() mkWire.Add(aWire.Wire()) mkWire.Add(aMirroredWire) myWireProfile = mkWire.Wire() # Telo: Iz profila se izdela telo myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile) aPrismVec = gp_Vec(0 , 0 , myHeight) myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face() , aPrismVec) # Telo: Dodamo zaokrožitve (fillet) mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape()) topology_traverser = Topo(myBody.Shape()) for aEdge in topology_traverser.edges(): mkFillet.Add(myThickness / 12. , aEdge) myBody = mkFillet.Shape() #Dodajanje grla na steklenico neckLocation = gp_Pnt(0, 0, myHeight) neckNormal = gp_DZ() neckAx2 = gp_Ax2(neckLocation, neckNormal) myNeckRadius = myThickness / 4 myNeckHeight = myHeight / 10 mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , \ myNeckHeight) myNeck = mkCylinder.Shape(); myBody = BRepAlgoAPI_Fuse(myBody, myNeck) # Izdelava votle steklenice faceToRemove = None zMax = -1; t = Topo(myBody.Shape()) k=1 for aFace in t.faces(): aSurface = BRep_Tool().Surface(aFace) if aSurface.GetObject().IsInstance('Geom_Plane'): aPlane = Handle_Geom_Plane().DownCast(aSurface).GetObject() aPnt = aPlane.Location() aZ = aPnt.Z() if aZ>zMax: faceToRemove = aFace facesToRemove = TopTools_ListOfShape() facesToRemove.Append(faceToRemove) myBody = BRepOffsetAPI_MakeThickSolid(myBody.Shape() , facesToRemove , \ -myThickness/50 , 1.e-3) # Threading : Create Surfaces aCyl1 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 0.99) aCyl2 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 1.05) # Threading : Define 2D Curves aPnt = gp_Pnt2d(2. * 3.141592 , myNeckHeight / 2.) aDir = gp_Dir2d(2. * 3.141592 , myNeckHeight / 4.) aAx2d = gp_Ax2d(aPnt , aDir) aMajor = 2. * 3.141592 aMinor = myNeckHeight / 10. anEllipse1 = Geom2d_Ellipse(aAx2d , aMajor , aMinor) anEllipse2 = Geom2d_Ellipse(aAx2d , aMajor , aMinor / 4) aArc2 = Geom2d_TrimmedCurve(anEllipse1.GetHandle() , 3.141592, 0.) aArc1 = Geom2d_TrimmedCurve(anEllipse2.GetHandle() , 3.141592, 0.) anEllipsePnt2 = anEllipse1.Value(0.) anEllipsePnt1 = anEllipse1.Value(3.141592) aSegment = GCE2d_MakeSegment(anEllipsePnt1 , anEllipsePnt2) # Threading : Build Edges and Wires aEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(aArc1.GetHandle() , aCyl1.GetHandle()) aEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment.Value() , aCyl1.GetHandle()) aEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(aArc2.GetHandle() , aCyl2.GetHandle()) aEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value() , aCyl2.GetHandle()) print dir(aEdge1OnSurf1) threadingWire1 = BRepBuilderAPI_MakeWire(aEdge1OnSurf1.Edge() , aEdge2OnSurf1.Edge()) threadingWire2 = BRepBuilderAPI_MakeWire(aEdge1OnSurf2.Edge() , aEdge2OnSurf2.Edge()) BRepLib().BuildCurves3d(threadingWire1.Wire()) BRepLib().BuildCurves3d(threadingWire2.Wire()) # Create Threading aTool = BRepOffsetAPI_ThruSections(True) aTool.AddWire(threadingWire1.Wire()) aTool.AddWire(threadingWire2.Wire()) aTool.CheckCompatibility(False) myThreading = aTool.Shape() # Izdelava sestava aRes = TopoDS_Compound() aBuilder = BRep_Builder() aBuilder.MakeCompound (aRes) aBuilder.Add (aRes, myBody.Shape()) aBuilder.Add (aRes, myThreading) # Izris oblike show_bottle(aPnt1) def draw_bottle(event=None): # Definiranje razdalj: širina, dolžina, višina myWidth = 50.0 myThickness = 30.0 myHeight = 70.0 # Define Points define_points(myWidth, myThickness, myHeight) if __name__ == '__main__': # OCC.Display.SimpleGui.init_display() returns multiple # values which are assigned here display, start_display, add_menu, add_function_to_menu = \ init_display() draw_bottle() #kličemo podprogram za izris bottle start_display() }}}