Changes between Initial Version and Version 1 of occt


Ignore:
Timestamp:
Nov 19, 2018, 11:40:35 AM (5 years ago)
Author:
Leon Kos
Comment:

Prvi draft za predstavitev PyOCCT

Legend:

Unmodified
Added
Removed
Modified
  • occt

    v1 v1  
     1== Uporaba modula PythonOCCT ==
     2
     3Projekt **PythonOCCT** je še ena priredba knjižnice OpenCASCADE 7.2.0 za programiranje v jeziku Python.
     4Od PythonOCC-ja se razlikuje v verziji OpenCASCADE in v klicanju metod.
     5
     6Statične funkcije se v **PythonOCC** uvozijo kar na modularnem nivoju:
     7
     8{{{#!python
     9from OCC.TodoDS import topods_Edge
     10}}}
     11
     12Med tem ko v PythonOCCT so statične funkcije znotraj razredov in imajo na koncu še podčrtaj
     13
     14{{{#!python
     15from OCCT.TopoDS import TopoDS
     16edge = TopoDS.Edge_(shape)
     17}}}
     18
     19Prav tako se v PythonOCCT ne uporablja več metod **GetHandle**, **Downcast** in **GetObject**, ker se že v kodi PythonOCCT vse avtomatsko to naredi:
     20
     21V **PythonOCC**
     22{{{#!python
     23handle_geom = line.Copy()
     24new_line = Handle_Geom_Line.Downcast(handle_geom).GetObject()
     25}}}
     26
     27V **PythonOCCT**
     28{{{#!python
     29new_line = line.Copy()
     30}}}
     31
     32To naredi stvari precej pitonične, saj lahko direktno ugotovimo tip geometrije z uporabo python metode **isinstance**:
     33
     34{{{#!python
     35# S pomočjo PythonOCC-ja preverimo če je TopoDS_Shape Geom_Plane.
     36hs = BRep_Tool_Surface(face)
     37downcast_result = Geom_Plane.DownCast(hs)
     38# Če je downcast_result tipa None, spremenljivka face ni Geom_Plane.
     39if downcast_result is None:
     40    return False
     41else:
     42    return True
     43}}}
     44
     45
     46{{{#!python
     47# S pomočjo PythonOCCT-ja preverimo če je TopoDS_Shape Geom_Plane.
     48hs = BRep_Tool_Surface(face)
     49if isinstance(hs, Geom_Plane):
     50    return True
     51else:
     52    return False
     53}}}
     54
     55=== Izdelava primera Bottle z uporabo programskega jezika Python in knjižnice OCCT ===
     56Naslednji primer prikazuje izdelavo primera BottleCAD. Podrobnejši razdelek posameznih delov programske kode dobimo na [[http://trac.lecad.si/vaje/wiki/OpenCascade|MakeBottleCAD(C++)]]. Za vizualizacijo se uporablja SALOME-8.5.0
     57
     58[[Image(bottle.png, width=480px, right)]]
     59{{{
     60#!python
     61##Uredil in posodobil 2018 Gregor Simič (gregor.simic@lecad.fs.uni-lj.si)
     62import math
     63
     64# from OCCT.gp import gp_Pnt, gp_OX, gp_Vec, gp_Trsf, gp_DZ, gp_Ax2, gp_Ax3, gp_Pnt2d, gp_Dir2d, gp_Ax2d
     65from OCCT.gp import gp_Pnt, gp, gp_Vec, gp_Trsf, gp_Ax2, gp_Ax3, gp_Pnt2d, gp_Dir2d, gp_Ax2d
     66# Classes gp_OX, gp_DZ are statical methods and in OCCT stored inside
     67# OCCT.gp.gp as OX_ and DZ_ respectively.
     68
     69from OCCT.GC import GC_MakeArcOfCircle, GC_MakeSegment
     70from OCCT.GCE2d import GCE2d_MakeSegment
     71from OCCT.Geom import Geom_Plane, Geom_CylindricalSurface, Geom_Surface
     72from OCCT.Geom2d import Geom2d_Ellipse, Geom2d_TrimmedCurve, Geom2d_Ellipse, Geom2d_Curve
     73from OCCT.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeFace, \
     74    BRepBuilderAPI_Transform
     75from OCCT.BRepPrimAPI import BRepPrimAPI_MakePrism, BRepPrimAPI_MakeCylinder
     76from OCCT.BRepFilletAPI import BRepFilletAPI_MakeFillet
     77from OCCT.BRepAlgoAPI import BRepAlgoAPI_Fuse
     78from OCCT.BRepOffsetAPI import BRepOffsetAPI_MakeThickSolid, BRepOffsetAPI_ThruSections
     79
     80# from OCC.Core.BRepLib import breplib
     81# In OCCT the modules preserve the case.
     82from OCCT.BRepLib import BRepLib
     83
     84# from OCC.Core.BRep import BRep_Tool_Surface, BRep_Builder
     85from OCCT.BRep import BRep_Tool, BRep_Builder
     86# OCCT does not have OCCT.Core but rather all modules are accessed directly
     87# from OCCT. Again BRep_Tool_Surface from OCC is a static method to create
     88# a Surface, hence in OCCT it is called from BRep_Tools as Surface_
     89
     90from OCCT.TopoDS import TopoDS, TopoDS_Edge, TopoDS_Compound
     91from OCCT.TopExp import TopExp_Explorer
     92from OCCT.TopAbs import TopAbs_EDGE, TopAbs_FACE
     93from OCCT.TopTools import TopTools_ListOfShape
     94
     95def face_is_plane(face):
     96    """
     97    Returns True if the TopoDS_Shape is a Geom_Plane, False otherwise.
     98    """
     99    hs = BRep_Tool.Surface_(face)
     100    # downcast_result = Geom_Plane.DownCast(hs)
     101    # OCCT 7.2.0 does not have the DownCast function anymore, in this case
     102    # we use we simply use the isinstance method to check if the shape
     103    # is a Geom_Plane.
     104    if isinstance(hs, Geom_Plane):
     105        return True
     106    else:
     107        # Othe cases when it returns false are, Geom_CylindricalSurface,
     108        # Geom_ToroidalSurface, Geom_SphericalSurface
     109        return False
     110
     111
     112def geom_plane_from_face(aFace):
     113    """
     114    Returns the geometric plane entity from a planar surface
     115    """
     116    # return Geom_Plane.DownCast(BRep_Tool.Surface_(aFace))
     117    return BRep_Tool.Surface_(aFace).Pln()
     118
     119
     120height = 70
     121width = 50
     122thickness = 30
     123
     124print("creating bottle")
     125# The points we'll use to create the profile of the bottle's body
     126aPnt1 = gp_Pnt(-width / 2.0, 0, 0)
     127aPnt2 = gp_Pnt(-width / 2.0, -thickness / 4.0, 0)
     128aPnt3 = gp_Pnt(0, -thickness / 2.0, 0)
     129aPnt4 = gp_Pnt(width / 2.0, -thickness / 4.0, 0)
     130aPnt5 = gp_Pnt(width / 2.0, 0, 0)
     131
     132aArcOfCircle = GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4)
     133aSegment1 = GC_MakeSegment(aPnt1, aPnt2)
     134aSegment2 = GC_MakeSegment(aPnt4, aPnt5)
     135
     136# Could also construct the line edges directly using the points instead of the resulting line
     137aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value())
     138aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value())
     139aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value())
     140
     141# Create a wire out of the edges
     142aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge(), aEdge2.Edge(), aEdge3.Edge())
     143
     144# Quick way to specify the X axis
     145# xAxis = gp_OX() # From OCC
     146xAxis = gp.OX_()
     147
     148# Set up the mirror
     149aTrsf = gp_Trsf()
     150aTrsf.SetMirror(xAxis)
     151
     152# Apply the mirror transformation
     153aBRespTrsf = BRepBuilderAPI_Transform(aWire.Wire(), aTrsf)
     154
     155# Get the mirrored shape back out of the transformation and convert back to a wire
     156aMirroredShape = aBRespTrsf.Shape()
     157
     158# A wire instead of a generic shape now
     159# aMirroredWire = topods.Wire(aMirroredShape) # From OCC
     160aMirroredWire = TopoDS.Wire_(aMirroredShape)
     161
     162# Combine the two constituent wires
     163mkWire = BRepBuilderAPI_MakeWire()
     164mkWire.Add(aWire.Wire())
     165mkWire.Add(aMirroredWire)
     166myWireProfile = mkWire.Wire()
     167
     168# The face that we'll sweep to make the prism
     169myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile)
     170
     171# We want to sweep the face along the Z axis to the height
     172aPrismVec = gp_Vec(0, 0, height)
     173myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face(), aPrismVec)
     174
     175# Add fillets to all edges through the explorer
     176mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape())
     177anEdgeExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_EDGE)
     178
     179while anEdgeExplorer.More():
     180    anEdge = TopoDS.Edge_(anEdgeExplorer.Current())
     181    mkFillet.Add(thickness / 12.0, anEdge)
     182
     183    anEdgeExplorer.Next()
     184
     185myBody = mkFillet
     186
     187# Create the neck of the bottle
     188neckLocation = gp_Pnt(0, 0, height)
     189# neckAxis = gp_DZ() # From OCC
     190neckAxis = gp.DZ_()
     191neckAx2 = gp_Ax2(neckLocation, neckAxis)
     192
     193myNeckRadius = thickness / 4.0
     194myNeckHeight = height / 10.0
     195
     196mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2, myNeckRadius, myNeckHeight)
     197
     198myBody = BRepAlgoAPI_Fuse(myBody.Shape(), mkCylinder.Shape())
     199
     200# Our goal is to find the highest Z face and remove it
     201faceToRemove = None
     202zMax = -1
     203
     204# We have to work our way through all the faces to find the highest Z face so we can remove it for the shell
     205aFaceExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_FACE)
     206while aFaceExplorer.More():
     207    # aFace = topods.Face(aFaceExplorer.Current()) # From OCC
     208    aFace = TopoDS.Face_(aFaceExplorer.Current())
     209
     210    if face_is_plane(aFace):
     211        aPlane = geom_plane_from_face(aFace)
     212
     213        # We want the highest Z face, so compare this to the previous faces
     214        aPnt = aPlane.Location()
     215        aZ = aPnt.Z()
     216        if aZ > zMax:
     217            zMax = aZ
     218            faceToRemove = aFace
     219
     220    aFaceExplorer.Next()
     221
     222facesToRemove = TopTools_ListOfShape()
     223facesToRemove.Append(faceToRemove)
     224
     225myBody = BRepOffsetAPI_MakeThickSolid(myBody.Shape(), facesToRemove, -thickness / 50.0, 0.001)
     226
     227# Set up our surfaces for the threading on the neck
     228neckAx2_Ax3 = gp_Ax3(neckLocation, gp.DZ_())
     229aCyl1 = Geom_CylindricalSurface(neckAx2_Ax3, myNeckRadius * 0.99)
     230aCyl2 = Geom_CylindricalSurface(neckAx2_Ax3, myNeckRadius * 1.05)
     231
     232# Set up the curves for the threads on the bottle's neck
     233aPnt = gp_Pnt2d(2.0 * math.pi, myNeckHeight / 2.0)
     234aDir = gp_Dir2d(2.0 * math.pi, myNeckHeight / 4.0)
     235anAx2d = gp_Ax2d(aPnt, aDir)
     236
     237aMajor = 2.0 * math.pi
     238aMinor = myNeckHeight / 10.0
     239
     240anEllipse1 = Geom2d_Ellipse(anAx2d, aMajor, aMinor)
     241anEllipse2 = Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4.0)
     242
     243anArc1 = Geom2d_TrimmedCurve(anEllipse1, 0, math.pi)
     244anArc2 = Geom2d_TrimmedCurve(anEllipse2, 0, math.pi)
     245
     246anEllipsePnt1 = anEllipse1.Value(0)
     247anEllipsePnt2 = anEllipse1.Value(math.pi)
     248
     249aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2)
     250
     251# Build edges and wires for threading
     252anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1)
     253anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment.Value(), aCyl1)
     254anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2)
     255anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value(), aCyl2)
     256
     257threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1.Edge(), anEdge2OnSurf1.Edge())
     258threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2.Edge(), anEdge2OnSurf2.Edge())
     259
     260# Compute the 3D representations of the edges/wires
     261# breplib.BuildCurves3d(threadingWire1.Shape()) # From OCC
     262# breplib.BuildCurves3d(threadingWire2.Shape()) # From OCC
     263BRepLib.BuildCurves3d_(threadingWire1.Shape())
     264BRepLib.BuildCurves3d_(threadingWire2.Shape())
     265
     266# Create the surfaces of the threading
     267aTool = BRepOffsetAPI_ThruSections(True)
     268aTool.AddWire(threadingWire1.Wire())
     269aTool.AddWire(threadingWire2.Wire())
     270aTool.CheckCompatibility(False)
     271myThreading = aTool.Shape()
     272
     273# Build the resulting compound
     274bottle = TopoDS_Compound()
     275aBuilder = BRep_Builder()
     276aBuilder.MakeCompound(bottle)
     277aBuilder.Add(bottle, myBody.Shape())
     278aBuilder.Add(bottle, myThreading)
     279print("bottle finished")
     280
     281# if __name__ == "__main__":
     282#     from OCC.Display.SimpleGui import init_display
     283#     display, start_display, add_menu, add_function_to_menu = init_display()
     284#     display.DisplayColoredShape(bottle, update=True)
     285#     start_display()
     286
     287# Display in GEOM
     288from GEOM_OCCT import fromPythonOCCT
     289fromPythonOCCT(bottle, 'bottle')
     290}}}