wiki:PythonOcc

Version 47 (modified by mprotic, 8 years ago) (diff)

--

PythonOCC omogoča enostavnejšo uporabo jedra modelirnika OpenCascade v jeziku Python. Prednost Pythona v primerjavi z C++ je:

  • Prenosljivosti. Programi se interpretirajo in jih ni potrebno prevajati zato delujejo na vseh operacijskih sistemih. So pa nekoliko počasnejši.
  • Enostavnejša namestitev potrebnih knjižnic, brez zahtevne konfiguracije povezovalnih parametrov, ki so značilni za C++.
  • Lažje učenje jezika. V interaktivnem načinu obstaja tudi refleksija oziroma dinamično prepoznavanje možnih ukazov v objektu.

Za vaje, si je potrebno na svojih računalnikih (postopek za 64-bitbe Windowse) pripraviti okolje, kot ga bomo uporabljali na avditornih vajah. Postopek priprave je naslendji:

  1. Python 3.4 interpreter jezika z osnovnimi knjižnicami
  2. PyQt 4.8.7 za upravljanje z okni
  3. PythonOCC povezava Pytona z jedrom OpenCascade.

OPOMBA: V primeru, da nam namestitveni program nepravilno namesti imenik na C:\OCC ga prestavimo v podimenik C:\Python34\Lib\site-packages

  1. PyCharm urejevalnik.
  2. Pred preizkusom prvih primerov je potrebno najprej prenesti datoteko qtDisplay.py, katero dobimo na dnu strani pod "Priponke". Nato, če ste pustili privzete lokacije inštalacij, na lokaciji C:\Python34\Lib\site-packages\OCC\Display zamenjate datoteko qtDisplay.py z istoimensko datoteko, katero ste pred tem prenesli.

OPOMBA: V primeru, da boste imeli kakršne koli težave, pri namestivi delovnega okolja, ki ga bomo potrebovali za vaje, za pomoč povprašajte demenstratorja Dejana Penkota ali Marka Protiča.

Neobvezno, vendar priporočljivo je namestiti še:

  1. iPython za interektivno delo
  2. NumPy? za delo z numeričnimi metodami in matrikami
  3. SciPy? za delo z znanstvenimi algoritmi

Vse tri naštete pakete lahko namestite direktno z namestitvijo Python distribucije Anaconda.

Predstavitev CAD-jedra Open CASCADE na primerih

Osnove gradnje modelov so podane na strani PythonOcc/primitives in PythonOcc/elbow

Uvod v modeliranje PythonOCC s 3D primitivi

V tem primeru je namen pokazati enostavne aplikacije:

  • izdelava menuja in dva podmenuja
  • ta dva menuja izdelata: i. kocko in ii. cilinder

Najprej kličemo knjižnico za enostaven uporabniški vmesnik SimpleGUI:

# -*- coding: utf-8 -*- 
from OCC.Display.SimpleGui import *

The next step is to init the display functions: V naslednjem koraku inicializiramo funkcije za display:

display, start_display, add_menu, add_function_to_menu = init_display()

3Dprimitives Let’s now define the two functions that create and display a box and a cylinder: Nato definiramo dve funkciji, ki izdelata kocko in cilinder:

def kocka(event=None):
    from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox
    display.EraseAll()
    my_box= BRepPrimAPI_MakeBox(10., 20., 30.)
    display.DisplayShape(my_box.Shape())

def valj(event=None):
    from OCC.BRepPrimAPI import BRepPrimAPI_MakeCylinder
    display.EraseAll()
    my_cylinder = BRepPrimAPI_MakeCylinder(60, 200)
    display.DisplayShape(my_cylinder.Shape())

Izdelava menija 'simple test' in dodajanje funkcij v podmenije:

add_menu('enostaven primer')
add_function_to_menu('enostaven primer', kocka)
add_function_to_menu('enostaven primer', valj)

Na koncu renderiramo 3D model:

display.View_Iso()
display.FitAll()

start_display() # Zanka start_display() je neskončna

Namesto uporabe klasičnih primitivov, lahko kocko zgradimo tudi z izvlekom žičnega modela.

# -*- coding: utf-8 -*-
## Izdelava kocke

from OCC.Display.SimpleGui import *
from OCC.BRepPrimAPI import *
from OCC.gp import *
from OCC.GC import *
from OCC.BRepBuilderAPI import *
#from OCC.TopoDS import *

display, start_display, add_menu, add_function_to_menu = init_display()

#Definiranje točk v prostoru
aPnt1 = gp_Pnt(0 , 0 , 0)
aPnt2 = gp_Pnt(10 , 0, 0)
aPnt3 = gp_Pnt(10 , 10 , 0)
aPnt4 = gp_Pnt(0, 10 , 0)

#Izdelava segmentov--definiranje geometrije
aSegment1 = GC_MakeSegment(aPnt1 , aPnt2)
aSegment2 = GC_MakeSegment(aPnt2 , aPnt3)
aSegment3 = GC_MakeSegment(aPnt3 , aPnt4)
aSegment4 = GC_MakeSegment(aPnt4 , aPnt1)

#Izdelava robov -- definiranje topologije
aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value())
aEdge2 = BRepBuilderAPI_MakeEdge(aSegment2.Value())
aEdge3 = BRepBuilderAPI_MakeEdge(aSegment3.Value())
aEdge4 = BRepBuilderAPI_MakeEdge(aSegment4.Value())

#Povezovanje robov v mrežo
aWire  = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,\
                                 aEdge3.Edge(), aEdge4.Edge())

#Telo: Iz profila se izdela telo
myFaceProfile = BRepBuilderAPI_MakeFace(aWire.Wire())

aPrismVec = gp_Vec(0 , 0 , 10)

myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face() , aPrismVec).Shape()

display.DisplayShape(myBody)
start_display()

Slikovni pregled izdelave 3D modela

  1. Definiranje točk v prostoru:
     aPnt1 = gp_Pnt(x_1 , y_1 , z_1) --> aPnt4 = gp_Pnt(x_4 , y_4 , z_4)
    
  2. Iz točk v prostoru se tvori robove (en rob je sestavljen iz najmanj dveh točk):
    myEdge1 = BRepBuilderAPI_MakeEdge(aPnt1, aPnt2) --> myEdge4 = BRepBuilderAPI_MakeEdge(aPnt4, aPnt1)
    
  3. Ko imamo vse robove izdelamo mrežo:
    myWire  = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge(), aEdge4.Edge())
    
  4. Iz mreže tvorimo površino (mreža mora biti zaprta):
    myFace = BRepBuilderAPI_MakeFace(myWire)
    
  5. Definiranje prostorskega vektorja, ki bo določal smer izvleka (ekstrudiranja) površine:
    myVec = gp_Vec(n_x , n_y , n_z)
    
  6. Z površino in smernim vektorjem izdelamo 3D model:
    myBody = BRepPrimAPI_MakePrism(myFace.Face() , myVec)
    

Dodajanje slike za izdelavo solid iz točk

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

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

Izris CAD prizme

## Izdelava prizme --primer bottle

from OCC.Display.SimpleGui import *
from OCC.BRepPrimAPI import *
from OCC.gp import *
from OCC.GC import *
from OCC.BRepBuilderAPI import *
from OCC.TopoDS import *

display, start_display, add_menu, add_function_to_menu = init_display()

myWidth = 50.0
myThickness = 30.0
myHeight = 70.0

#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 segmentov--definiranje geometrije
aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4)
aSegment1 = GC_MakeSegment(aPnt1 , aPnt2)
aSegment2 = GC_MakeSegment(aPnt4 , aPnt5)

#Izdelava robov -- definiranje topologije
aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value())
aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value())
aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value())

#Povezovanje robov v mrežo
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).Shape()

display.DisplayShape(myBody)
start_display()

Povzetek prve vaje

Prikaz enostavnega izvoza STEP formata za eno obliko

# Vključimo knjižnico za izvoz STEP formata
from OCC.Utils.DataExchange.STEP import STEPExporter

from OCC.BRepPrimAPI import *

# Pripravimo enostaven CAD primer za izvoz v STEP format
my_box_shape = BRepPrimAPI_MakeBox(50,50,50).Shape() # Izdelava kocke

# Obliko my_box_shape izvozimo v STEP format
my_step_exporter = STEPExporter("result_export_single.stp") # Določitev imena file.a
my_step_exporter.add_shape(my_box_shape)
my_step_exporter.write_file()

Prikaz enostavnega izvoza STEP formata za več oblik

# Vključimo knjižnico za izvoz STEP formata
from OCC.Utils.DataExchange.STEP import STEPExporter

from OCC.BRepPrimAPI import *

# Pripravimo enostavna CAD primera za izvoz v STEP format
my_box_shape = BRepPrimAPI_MakeBox(50,50,50).Shape() # Izdelava kocke
my_sphere_shape = BRepPrimAPI_MakeSphere(20).Shape() # Izdelava krogle

# Obliki my_box_shape in my_sphere_shape izvozimo v STEP format
my_step_exporter = STEPExporter("result_export_multi.stp") # Določitev imena file.a
my_step_exporter.add_shape(my_box_shape)
my_step_exporter.add_shape(my_sphere_shape) #funkcijo ADD uporabimo za dodajanje oblik v STEP format
my_step_exporter.write_file()

Prikaz izvoza CAD modelov z barvami in layer.ji

# Vključimo knjižnico za izvoz STEP formata
from OCC.Utils.DataExchange.STEP import StepOCAF_Export

from OCC.BRepPrimAPI import *

# Pripravimo enostavna CAD primera za izvoz v STEP format
my_box_shape = BRepPrimAPI_MakeBox(50,50,50).Shape() # Izdelava kocke
my_sphere_shape = BRepPrimAPI_MakeSphere(20).Shape() # Izdelava krogle

# Export to STEP
my_step_exporter = StepOCAF_Export("result_export_multi_color_layer.stp") # Določitev imena file.a
my_step_exporter.set_color(1,0,0) # določitev barve (rdeča) -> RedGreenBlue paleta barv (RGB)
my_step_exporter.set_layer('red') # določitev layer.ja
my_step_exporter.add_shape(my_box_shape) # izbira oblike za izbrane parametre my_box_shape
my_step_exporter.set_color(0,1,0) 
my_step_exporter.set_layer('green')
my_step_exporter.add_shape(my_sphere_shape)
my_step_exporter.write_file()

Pisanje datotek STL

Stereolitografski format je primeren za prikaz v spletnih pregledovalnikih (threejs z WebGL) saj vključuje zapis v trikotnikih. Ne vključuje barv in lahko izvozi le en Shape(). Da zmanjšamo velikost datoteke, namesto ASCII izberemo binarni format z "False". Naslednji primer shrani enotsko kroglo:

# -*- coding: utf-8 -*-
from OCC.StlAPI import *
from OCC.BRepPrimAPI import *
my_sphere_shape = BRepPrimAPI_MakeSphere(1).Shape()
stl_writer = StlAPI()
stl_writer.Write(my_sphere_shape, "krogla.stl", False)

Uporaba funkcije zaokrožitve, pozicioniranje valja na izbrano mesto, združevanje CAD modelov ter izvoz v STEP format

V naslednjem primeru so prikazane naslednje funkcije:

  • zaokrožitve
  • pozicioniranje elementa
  • združevanje CAD modelov
  • enostaven izvoz CAD modela v STEP format
##Copyright 2011 Simon Kulovec (simon.kulovec@lecad.si)
##This file is part of pythonOCC.

## Importanje razlicnih knjiznic

# Uporabniski 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.BRep import *
from OCC.Utils.DataExchange.STEP import STEPExporter

# OCC.Display.SimpleGui.init_display() returns multiple
# values which are assigned here
display, start_display, add_menu, add_function_to_menu = \
init_display()

# Definiranje spremenljivk
myWidth = 50.0
myThickness = 30.0
myHeight = 70.0

# Definiranje zacetnih tock
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 zaokrozitve (fillet)
mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape())
topology_traverser = Topo(myBody.Shape())
for aEdge in topology_traverser.edges(): #z uporabo for zanke iščemo robove na CAD modelu in jih zaokrožujemo s funkcijo mkFillet in združujemo z .Add
    mkFillet.Add(myThickness / 12. , aEdge) #velikost zaokrožitve myThickness / 12.
myBody = mkFillet.Shape() #vse zaokrožitve priključimo k prvotni obliki myBody

# Dodajanje grla na steklenico (valj)
neckLocation = gp_Pnt(0, 0, myHeight) #Določitev lokacije valja
neckNormal = gp_DZ() #smer normale, v katero bomo valj izvlekli
neckAx2 = gp_Ax2(neckLocation, neckNormal) 

myNeckRadius = myThickness / 4 #radij valja
myNeckHeight = myHeight / 10 # višina valja

mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , \
                                          myNeckHeight)
myNeck = mkCylinder.Shape();

myBody = BRepAlgoAPI_Fuse(myBody, myNeck) #dodajanje valja k obliki myBody

# Izdelava sestava
aRes = TopoDS_Compound() #Določitev spremenljivke za sestav
aBuilder = BRep_Builder()
aBuilder.MakeCompound (aRes)
aBuilder.Add (aRes, myBody.Shape()) #Dodajanje različnih oblik v sestav aRes

# Export to STEP ()
my_step_exporter = STEPExporter("export_step_file.stp") #Določevanje imena STEP file.a 
my_step_exporter.add_shape(aRes) #Dodajanje oblike v STEP file
my_step_exporter.write_file()

# Izris oblike
display.EraseAll()
print dir(display)
display.DisplayShape(aRes)

start_display()

Povzetek druge vaje

Izdelava CAD kocke z predhodno definiranimi točkami (Uporaba for zanke za generiranje točk, površin, mreže)

import sys
from OCC.Display.SimpleGui import *

from OCC.gp import gp_Pnt
from OCC.GC import GC_MakeSegment
from OCC.BRepBuilderAPI import \
  BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakeWire,\
  BRepBuilderAPI_MakeShell, BRepBuilderAPI_MakeSolid
from OCC.BRep import BRep_Builder
from OCC.TopoDS import TopoDS_Shell, TopoDS_Solid
from OCC import StlAPI

mesh = {
  "vertices":[[-0.2,-0.2,0.2],[0.2,-0.2,0.2],[0.2,0.2,0.2],[-0.2,0.2,0.2],\
                  [-0.2,-0.2,0.6000000000000001],[0.2,-0.2,0.6000000000000001],\
                  [0.2,0.2,0.6000000000000001],[-0.2,0.2,0.6000000000000001]],
  "faces":[[3,2,1,0],[4,5,6,7],[7,6,2,3],[5,4,0,1],[6,5,1,2],[4,7,3,0]]
}

def main():

  vertices = [ gp_Pnt(p[0],p[1],p[2]) for p in mesh['vertices'] ]
  oFaces = []

  builder = BRep_Builder()
  shell = TopoDS_Shell()
  builder.MakeShell(shell)

  for face in mesh['faces']:
    edges = []
    face.reverse()
    for i in range(len(face)):
      cur = face[i]
      nxt = face[(i+1)%len(face)]
      segment = GC_MakeSegment(vertices[cur],vertices[nxt])
      edges.append(BRepBuilderAPI_MakeEdge(segment.Value()))

    wire = BRepBuilderAPI_MakeWire()
    for edge in edges:
      wire.Add(edge.Edge())

    oFace = BRepBuilderAPI_MakeFace(wire.Wire())

    builder.Add(shell, oFace.Shape())
    display.DisplayShape(shell)

if __name__ == '__main__':
    display, start_display, add_menu, add_function_to_menu = \
        init_display()
    main()
    start_display()

Branje vrednosti iz datoteke (input_file.dat) in generiranje CAD modela (Parametriziran CAD model)

Datoteka: input_file.dat

70 70 70

Programska koda (.py)

#Odpiranje datoteke input_file.dat, ter branje iz nje v izbrane spremenljivke
#Simon Kulovec
from OCC.Display.SimpleGui import *
from OCC.BRepPrimAPI import *

display, start_display, add_menu, add_function_to_menu = init_display()

#Branje iz datoteke: input_file.dat
f= open("input_file.dat", "r")
lines = f.readlines()
box0 = [] #Vektor v katerega shranjujemo prebrane vrednosti

#Stevilo prebranih vrstic je 1
for i in range(1): 
    x,y,z=[eval(s) for s in lines[i].split(" ")]
    box0.append(x)
    box0.append(y)
    box0.append(z)
    #Izpis prebranih vrednosti iz datoteke v terminal
    print "%4.1f %4.1f %4.1f "  % ( box0[i], box0[i+1],\
                                        box0[i+2])
f.close()


my_box = BRepPrimAPI_MakeBox(box0[0],box0[1],box0[2]).Shape()

display.DisplayShape(my_box)
start_display()

Prikaz izdelave kocke in uporaba funkcije krožnega izvleka

##Prikaz izdelave kocke in uporaba funkcije krožnega izvleka
##S.Kulovec, 2011

from OCC.gp import *
from OCC.BRepPrimAPI import *
from OCC.TopExp import *
from OCC.TopAbs import *
import OCC.TopoDS
from OCC.BRep import *
from OCC.Geom import *
from OCC.GCE2d import *
from OCC.Geom2d import *
from OCC.BRepLib import *
from OCC.BRepFeat import *

from OCC.Utils.Topology import Topo
from OCC.BRepBuilderAPI import *

import sys, time
from OCC.Display.SimpleGui import *
display, start_display, add_menu, add_function_to_menu = init_display()

S = BRepPrimAPI_MakeBox(400.,250.,300.).Shape()
faces = list(Topo(S).faces())
F1 = faces[2]
surf = BRep_Tool_Surface(F1)
Pl = Handle_Geom_Plane_DownCast(surf)

D = gp.gp_OX()

MW1 = BRepBuilderAPI_MakeWire() 
p1 = gp_Pnt2d(100.,100.)
p2 = gp_Pnt2d(200.,100.)
aline = GCE2d_MakeLine(p1,p2).Value()
MW1.Add(BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)).Edge())

p1 = gp_Pnt2d(200.,100.)
p2 = gp_Pnt2d(150.,200.)
aline = GCE2d_MakeLine(p1,p2).Value()
MW1.Add(BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)).Edge())

p1 = gp_Pnt2d(150.,200.)
p2 = gp_Pnt2d(100.,100.)
aline = GCE2d_MakeLine(p1,p2).Value()
MW1.Add(BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)).Edge())

MKF1 = BRepBuilderAPI_MakeFace() 
MKF1.Init(surf,False)
MKF1.Add(MW1.Wire())
FP = MKF1.Face()
BRepLib_BuildCurves3d(FP)
MKrev = BRepFeat_MakeRevol(S,FP,F1,D,1,True)
F2 = faces[4]
MKrev.Perform(F2)
display.EraseAll()
display.DisplayShape(MKrev.Shape())

start_display()

Napotki

Q: Zanima me kako se v PythonOCC dela luknje oz izvrtine(ali izreze). Katere funkcije se uporablja?

A: Podobno kot fuse je za izreze cut.

import OCC.Utils.Construct as construct
drzalo = construct.boolean_fuse(roka,nosilec) #celoten sestav
drzalo = construct.boolean_cut(drzalo, izvrtina)

Boolove operacije

Boolove operacije.

Q: Rad bi zaokrožil le robove profila, ne pa tudi prereza.

A: Če želimo zaokrožiti le določene robove lahko uporabimo različne teste. Naslednji primer naredi kopijo stebra in v zanki preiskovalca topologije dodaja robove, ki jih je potrebno zaokrožiti tako, da preverja višino začetne in končne točke robu. V primeru, da točki nisti v ravnini (X,Y) ga zaokroži. Velikost zaokrožitve je lahko največ tolikšna, da se še da normalno zaokrožiti označene robove.

# Telo: Dodamo zaokrožitve (fillet)
mkFillet = BRepFilletAPI_MakeFillet(steber.Shape())
topology_traverser = Topo(steber.Shape())
for aEdge in topology_traverser.edges():
    first, last = TopExp().FirstVertex(aEdge), TopExp().LastVertex(aEdge)
    first_vert, last_vert = BRep_Tool().Pnt(first), BRep_Tool().Pnt(last)
    if first_vert.Z() != last_vert.Z():
        mkFillet.Add(1.2, aEdge)
display.DisplayShape(mkFillet.Shape())        

Q: Kako postavimo model v drugi položaj?

A: Okoli osi v prostoru lahko rotirate:

    LokacijaOsi1 = gp_Pnt(8, 45, -100) 
    RotacijaOs1 = gp_Ax1(LokacijaOsi1, gp_Dir(0,0,1)) #Os rotacije
    TransfRot1 = gp_Trsf()
    TransfRot1.SetRotation(RotacijaOs1, t1)
    J19 = BRepBuilderAPI_Transform(J18, TransfRot1).Shape()

Translacija je še lažja:

    Premik = gp_Vec(-130, -870, -2530)
    Translacija = gp_Trsf()
    Translacija.SetTranslation(Premik)
    rezultat = BRepBuilderAPI_Transform(J17, Translacija).Shape()

Ostale funkcije so opisane v http://api.pythonocc.org/OCC.gp.gp_Trsf-class.html

Povezave in navodila za modeliranje z OCCT

Attachments (11)