wiki:python

Version 9 (modified by skulovec, 12 years ago) (diff)

Dodani primeri za uporabo PythonOCC

Python

Prvi program

  1. Odpremo IDLE (Python GUI) in odtipkamo naslednjo vrstico
    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

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

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:

# -*- 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.

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().

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)

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

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

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

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

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

# Izdelava mreže
aWire  = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge())

Uporaba funkcij za izdelavo objektov v prostoru

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

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 MakeBottleCAD(C++).

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

Attachments (26)