Version 71 (modified by 8 years ago) (diff) | ,
---|
-
-
Predstavitev CAD-jedra Open CASCADE na primerih
- Uvod v modeliranje PythonOCC s 3D primitivi
- Slikovni pregled izdelave 3D modela
- Pregled uporabljenih OCC knjižnic
- Inicializacija zaslona in izdelava grafičnega vmesnika
- Risanje točk v prostoru
- Izdelava robnih elementov
- Povezovanje robnih elementov v mreže
- Uporaba funkcij za izdelavo objektov v prostoru
- Risanje geometrijskih primitivov
- Risanje različnih tipov robov
- Risanje prerezane piramide
- Izdelava primera Bottle z uporabo programskega jezika Python in …
- Izris CAD prizme
- Povzetek prve vaje
- Povzetek druge vaje
- Napotki
-
Predstavitev CAD-jedra Open CASCADE na primerih
- Povezave in navodila za modeliranje z OCCT
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 osebnem računalniku z 64-bitnimi Windows-i pripraviti okolje po naslednjih korakih:
- Anaconda upravljalnik paketov.
- V terminalu (Start->Run cmd) napišite ukaz:
conda install -c https://conda.anaconda.org/dlr-sc pythonocc-core=0.17
- PyCharm Community urejevalnik (ne Proffesional).
- Ustvarite datoteko
core-hello.py
z naslednjo vsebino in preverite ali vam prikaže kocko v 3D.from OCC.Display.SimpleGui import init_display from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox display, start_display, add_menu, add_function_to_menu = init_display() my_box = BRepPrimAPI_MakeBox(10., 20., 30.).Shape() display.DisplayShape(my_box, update=True) start_display()
Novejše verzije pythonOCC lahko namestite z ukazom:
- Windows -> Start -> cmd -> desnoklik miške -> Run as administrator (prijavite se kot skrbnik, če vas le to okna vprašajo).
- Seznam verzij pregledate z
anaconda search -t conda pythonocc-core
- Nočno verzijo namestimo z
conda install -c https://conda.anaconda.org/tpaviot pythonocc-core=nightly
Predstavitev CAD-jedra Open CASCADE na primerih
Osnove gradnje modelov so podane na strani PythonOcc/primitives in PythonOcc/elbow
Več primerov lahko najdete na https://github.com/tpaviot/pythonocc-core/tree/master/examples.
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 *
V naslednjem koraku inicializiramo funkcije za display:
display, start_display, add_menu, add_function_to_menu = init_display()
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()) ''' #Robove se lahko določi tudi direktno s točkami: aEdge1 = BRepBuilderAPI_MakeEdge(aPnt1, aPnt2) aEdge2 = BRepBuilderAPI_MakeEdge(aPnt2, aPnt3) aEdge3 = BRepBuilderAPI_MakeEdge(aPnt3, aPnt4) aEdge4 = BRepBuilderAPI_MakeEdge(aPnt4, aPnt1) ''' #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() #Spodaj so zakomentirani ukazi za prikazovanje posameznih delov. ''' #Prikaz točk display.DisplayShape(aPnt1) display.DisplayShape(aPnt2) display.DisplayShape(aPnt3) display.DisplayShape(aPnt4) ''' ''' #Prikaz robov display.DisplayShape(aEdge1.Shape()) display.DisplayShape(aEdge2.Shape()) display.DisplayShape(aEdge3.Shape()) display.DisplayShape(aEdge4.Shape()) ''' ''' #Prikaz mreže display.DisplayShape(aWire.Shape()) ''' ''' #Prikaz profila display.DisplayShape(myFaceProfile.Shape()) ''' #Prikaz telesa display.DisplayShape(myBody) start_display()
Slikovni pregled izdelave 3D modela
- Definiranje točk v prostoru:
aPnt1 = gp_Pnt(x_1 , y_1 , z_1) --> aPnt4 = gp_Pnt(x_4 , y_4 , z_4)
- 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)
- Ko imamo vse robove izdelamo mrežo:
myWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge(), aEdge4.Edge())
- Iz mreže tvorimo površino (mreža mora biti zaprta):
myFace = BRepBuilderAPI_MakeFace(myWire)
- Definiranje prostorskega vektorja, ki bo določal smer izvleka (ekstrudiranja) površine:
myVec = gp_Vec(n_x , n_y , n_z)
- Z površino in smernim vektorjem izdelamo 3D model:
myBody = BRepPrimAPI_MakePrism(myFace.Face() , myVec)
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()
Risanje različnih tipov robov
##Copyright 2009-2015 Thomas Paviot (tpaviot@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC is free software: you can redistribute it and/or modify ##it under the terms of the GNU Lesser General Public License as published by ##the Free Software Foundation, either version 3 of the License, or ##(at your option) any later version. ## ##pythonOCC is distributed in the hope that it will be useful, ##but WITHOUT ANY WARRANTY; without even the implied warranty of ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##GNU Lesser General Public License for more details. ## ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>. import math from OCC.gp import gp_Pnt, gp_Lin, gp_Ax1, gp_Dir, gp_Elips, gp_Ax2 from OCC.BRepBuilderAPI import (BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeVertex) from OCC.TColgp import TColgp_Array1OfPnt from OCC.Geom import Geom_BezierCurve from OCC.Display.SimpleGui import init_display display, start_display, add_menu, add_function_to_menu = init_display() def edge(event=None): # The blue edge BlueEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(-80, -50, -20), gp_Pnt(-30, -60, -60)) V1 = BRepBuilderAPI_MakeVertex(gp_Pnt(-20, 10, -30)) V2 = BRepBuilderAPI_MakeVertex(gp_Pnt(10, 7, -25)) YellowEdge = BRepBuilderAPI_MakeEdge(V1.Vertex(), V2.Vertex()) #The white edge line = gp_Lin(gp_Ax1(gp_Pnt(10, 10, 10), gp_Dir(1, 0, 0))) WhiteEdge = BRepBuilderAPI_MakeEdge(line, -20, 10) #The red edge Elips = gp_Elips(gp_Ax2(gp_Pnt(10, 0, 0), gp_Dir(1, 1, 1)), 60, 30) RedEdge = BRepBuilderAPI_MakeEdge(Elips, 0, math.pi/2) # The green edge and the both extreme vertex P1 = gp_Pnt(-15, 200, 10) P2 = gp_Pnt(5, 204, 0) P3 = gp_Pnt(15, 200, 0) P4 = gp_Pnt(-15, 20, 15) P5 = gp_Pnt(-5, 20, 0) P6 = gp_Pnt(15, 20, 0) P7 = gp_Pnt(24, 120, 0) P8 = gp_Pnt(-24, 120, 12.5) array = TColgp_Array1OfPnt(1, 8) array.SetValue(1, P1) array.SetValue(2, P2) array.SetValue(3, P3) array.SetValue(4, P4) array.SetValue(5, P5) array.SetValue(6, P6) array.SetValue(7, P7) array.SetValue(8, P8) curve = Geom_BezierCurve(array) ME = BRepBuilderAPI_MakeEdge(curve.GetHandle()) GreenEdge = ME V3 = ME.Vertex1() V4 = ME.Vertex2() display.DisplayColoredShape(BlueEdge.Edge(), 'BLUE') display.DisplayShape(V1.Vertex()) display.DisplayShape(V2.Vertex()) display.DisplayColoredShape(WhiteEdge.Edge(), 'WHITE') display.DisplayColoredShape(YellowEdge.Edge(), 'YELLOW') display.DisplayColoredShape(RedEdge.Edge(), 'RED') display.DisplayColoredShape(GreenEdge.Edge(), 'GREEN') display.DisplayShape(V3) display.DisplayShape(V4, update=True) if __name__ == '__main__': edge() start_display()
Risanje prerezane piramide
##Copyright 2009-2015 Thomas Paviot (tpaviot@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC is free software: you can redistribute it and/or modify ##it under the terms of the GNU Lesser General Public License as published by ##the Free Software Foundation, either version 3 of the License, or ##(at your option) any later version. ## ##pythonOCC is distributed in the hope that it will be useful, ##but WITHOUT ANY WARRANTY; without even the implied warranty of ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##GNU Lesser General Public License for more details. ## ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>. import math from OCC.gp import gp_Dir, gp_Pln, gp_Ax3, gp_XOY from OCC.BRepPrimAPI import BRepPrimAPI_MakeBox from OCC.BRepOffsetAPI import BRepOffsetAPI_DraftAngle from OCC.Precision import precision_Angular from OCC.BRep import BRep_Tool_Surface from OCC.TopExp import TopExp_Explorer from OCC.TopAbs import TopAbs_FACE from OCC.Geom import Handle_Geom_Plane_DownCast from OCC.TopoDS import topods_Face from OCC.Display.SimpleGui import init_display display, start_display, add_menu, add_function_to_menu = init_display() def draft_angle(event=None): S = BRepPrimAPI_MakeBox(200., 300., 150.).Shape() adraft = BRepOffsetAPI_DraftAngle(S) topExp = TopExp_Explorer() topExp.Init(S, TopAbs_FACE) while topExp.More(): face = topods_Face(topExp.Current()) surf = Handle_Geom_Plane_DownCast(BRep_Tool_Surface(face)).GetObject() dirf = surf.Pln().Axis().Direction() ddd = gp_Dir(0, 0, 1) if dirf.IsNormal(ddd, precision_Angular()): adraft.Add(face, ddd, math.radians(15), gp_Pln(gp_Ax3(gp_XOY()))) topExp.Next() adraft.Build() display.DisplayShape(adraft.Shape(), update=True) if __name__ == '__main__': draft_angle() 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) ##Uredil in posodobil 2015 Dejan Penko (dejan.penko@lecad.fs.uni-lj.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.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 #Naslednja podprograma "face_is_plane" in "geom_plane_from_face" sta napisana za pomoč v nadaljevanju programa def face_is_plane(face): """ Vrne True če je TopoDS_Shape ravnina, False v nasprotnem primeru """ hs = BRep_Tool_Surface(face) downcast_result = Handle_Geom_Plane.DownCast(hs) # Vrednost je "null", če se izvedba tega podprograma ne izvede pravilo ali je ni mogoče izvesti. Iz tega sledi, da profil ni ravnina if downcast_result.IsNull(): return False else: return True def geom_plane_from_face(aFace): """ Vrne subjekt geometrične ravnine iz ravninske površine """ return Handle_Geom_Plane.DownCast(BRep_Tool_Surface(aFace)).GetObject() def show_bottle(aRes): display.EraseAll() #print (dir(display)) display.DisplayShape(aRes) def define_body(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 #Definiranje robov aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value()) aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value()) aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value()) #Definiranje robov iz mreže aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge()) ## Izdelava celotnega profila - mirror #Definiramo os zrcaljenja (os X) xAxis = gp_OX() #Nastavimo "zrcalo" aTrsf = gp_Trsf() aTrsf.SetMirror(xAxis) #Uporabimo zrcalno transformacijo aBRepTrsf = BRepBuilderAPI_Transform(aWire.Shape() , aTrsf) #Zrcalno obliko dobimo nazaj iz transformacije in pretvorimo v mrežo aMirroredShape = aBRepTrsf.Shape() aMirroredWire = topods_Wire(aMirroredShape) #Kombiniramo dve konsistentni mreži 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) #Dodamo zaokrožitve (fillet) s pomočjo t. i. Explorerja mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape()) anEdgeExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_EDGE) while anEdgeExplorer.More(): anEdge = topods.Edge(anEdgeExplorer.Current()) mkFillet.Add(myThickness / 12.0, anEdge) anEdgeExplorer.Next() myBody = mkFillet ##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; myBody = BRepAlgoAPI_Fuse(myBody.Shape(), myNeck.Shape()) ## Izdelava votle steklenice #CILJ: Poiščemo najvišji Z profil in ga odstranimo faceToRemove = None zMax = -1; #Če želimo najti najvišji Z profil, katerega želimo odstraniti iz lupine, je potrebno iti skozi vse profile aFaceExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_FACE) while aFaceExplorer.More(): aFace = topods.Face(aFaceExplorer.Current()) if face_is_plane(aFace): aPlane = geom_plane_from_face(aFace) # We want the highest Z face, so compare this to the previous faces aPnt = aPlane.Location() aZ = aPnt.Z() if aZ > zMax: zMax = aZ faceToRemove = aFace aFaceExplorer.Next() facesToRemove = TopTools_ListOfShape() facesToRemove.Append(faceToRemove) myBody = BRepOffsetAPI_MakeThickSolid(myBody.Shape() , facesToRemove , \ -myThickness/50 , 1.e-3) ## Navoj na vratu steklenice: #Ustvarjanje površine aCyl1 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 0.99) aCyl2 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 1.05) #Definiranje 2D krivulje navoja aPnt = gp_Pnt2d(2. * math.pi , myNeckHeight / 2.) aDir = gp_Dir2d(2. * math.pi , myNeckHeight / 4.) aAx2d = gp_Ax2d(aPnt , aDir) aMajor = 2.0 * math.pi aMinor = myNeckHeight / 10. anEllipse1 = Geom2d_Ellipse(aAx2d , aMajor , aMinor) anEllipse2 = Geom2d_Ellipse(aAx2d , aMajor , aMinor / 4.0) anArc1 = Geom2d_TrimmedCurve(Handle_Geom2d_Ellipse(anEllipse1), 0, math.pi) anArc2 = Geom2d_TrimmedCurve(Handle_Geom2d_Ellipse(anEllipse2), 0, math.pi) anEllipsePnt2 = anEllipse1.Value(0.) anEllipsePnt1 = anEllipse1.Value(math.pi) aSegment = GCE2d_MakeSegment(anEllipsePnt1 , anEllipsePnt2) #Robovi in mreže aEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1.GetHandle() , aCyl1.GetHandle()) aEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment.Value() , aCyl1.GetHandle()) aEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2.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()) #3D predstava robov/mrež breplib.BuildCurves3d(threadingWire1.Shape()) breplib.BuildCurves3d(threadingWire2.Shape()) #Površina navoja 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_body(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.STEPControl import * 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 step_writer = STEPControl_Writer() step_writer.Transfer(my_box_shape, STEPControl_AsIs) step_writer.Write("result_export_single.stp")
Prikaz enostavnega izvoza STEP formata za več oblik
# Vključimo knjižnico za izvoz STEP formata from OCC.STEPControl import * 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 step_writer = STEPControl_Writer() step_writer.Transfer(my_box_shape, STEPControl_AsIs) step_writer.Transfer(my_sphere_shape, STEPControl_AsIs) step_writer.Write("result_export_multi.stp")
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.
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
Prikaz torus modela v brskalniku
#!/usr/bin/env python ##Copyright 2009-2014 Thomas Paviot (tpaviot@gmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC is free software: you can redistribute it and/or modify ##it under the terms of the GNU Lesser General Public License as published by ##the Free Software Foundation, either version 3 of the License, or ##(at your option) any later version. ## ##pythonOCC is distributed in the hope that it will be useful, ##but WITHOUT ANY WARRANTY; without even the implied warranty of ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##GNU Lesser General Public License for more details. ## ##You should have received a copy of the GNU Lesser General Public License ##along with pythonOCC. If not, see <http://www.gnu.org/licenses/>. from OCC.Display.WebGl import threejs_renderer from OCC.BRepPrimAPI import BRepPrimAPI_MakeTorus torus_shp = BRepPrimAPI_MakeTorus(20., 10.).Shape() my_renderer = threejs_renderer.ThreejsRenderer(background_color="#123345") my_renderer.DisplayShape(torus_shp)
Povezave in navodila za modeliranje z OCCT
- PythonOCC API’s dokumentacija na spletni strani
- Primeri PythonOCC
- Vizualizacija s PythonOCC -- v obliki PDF
- Modelling algorithms za OpenCASCADE 6.6
- Modelling data
Attachments (11)
-
boolove-operacije.svg (23.4 KB) - added by 12 years ago.
Boolove operacije
-
points-solid.svg (49.9 KB) - added by 12 years ago.
Dodajanje slike za izdelavo solid iz točk
-
3Dprimitives.png (16.0 KB) - added by 12 years ago.
3Dprimitives
-
VisualizationOfGeometryWithUtilisingpythonOCC.pdf (1.3 MB) - added by 12 years ago.
Vizualizacija s PythonOCC
-
modalg.pdf (728.6 KB) - added by 11 years ago.
Modelling algorithms za OpenCASCADE 6.6
-
modata.pdf (573.0 KB) - added by 11 years ago.
Modeling Data
- qtDisplay.py (9.9 KB) - added by 9 years ago.
-
bottle.png (68.3 KB) - added by 9 years ago.
"bottle" primer - slikovni prikaz
- edge_primer.PNG (19.9 KB) - added by 8 years ago.
- prerezana_piramida.PNG (26.8 KB) - added by 8 years ago.
- torus_webgl.PNG (348.8 KB) - added by 8 years ago.