| 153 | | == Predstavitev CAD-jedra Open CASCADE na primerih == |
| 154 | | === Pregled uporabljenih OCC knjižnic === |
| 155 | | {{{ |
| 156 | | #!python |
| 157 | | ## Importanje različnih knjižnic |
| 158 | | |
| 159 | | # Uporabniški vmesnik GUI |
| 160 | | from OCC.Display.SimpleGui import * |
| 161 | | |
| 162 | | # Matematična knjižnica |
| 163 | | import math |
| 164 | | |
| 165 | | # OpenCascade |
| 166 | | from OCC.gp import * #točke |
| 167 | | from OCC.BRepBuilderAPI import * #gradimo robove, segmente, mreže ... |
| 168 | | from OCC.BRepPrimAPI import * #izdelava osnovnih geometrijskih primitivov |
| 169 | | from OCC.BRepFilletAPI import * #izdelava zaokrožitev |
| 170 | | }}} |
| 171 | | |
| 172 | | Točnejša navodila, opis funkcij in knjižnic lahko dobimo v PythonOCC dokumentaciji. |
| 173 | | |
| 174 | | === Inicializacija zaslona in izdelava grafičnega vmesnika=== |
| 175 | | {{{ |
| 176 | | #!python |
| 177 | | # OCC.Display.SimpleGui.init_display() returns multiple |
| 178 | | # values which are assigned here |
| 179 | | display, start_display, add_menu, add_function_to_menu = \ |
| 180 | | init_display() |
| 181 | | draw_bottle() #kličemo CAD model, ki ga želimo prikazati na zaslonu |
| 182 | | start_display() |
| 183 | | }}} |
| 184 | | === Risanje točk v prostoru === |
| 185 | | Izdelava točk v prostoru je najosnovnejša operacija v OCC. |
| 186 | | {{{ |
| 187 | | #!python |
| 188 | | # Definiranje začetnih točk |
| 189 | | aPnt1 = gp_Pnt(-myWidth / 2. , 0 , 0) |
| 190 | | aPnt2 = gp_Pnt(-myWidth / 2. , -myThickness / 4. , 0) |
| 191 | | aPnt3 = gp_Pnt(0 , -myThickness / 2. , 0) |
| 192 | | aPnt4 = gp_Pnt(myWidth / 2. , -myThickness / 4. , 0) |
| 193 | | aPnt5 = gp_Pnt(myWidth / 2. , 0 , 0) |
| 194 | | }}} |
| 195 | | |
| 196 | | === Izdelava robnih elementov === |
| 197 | | V naslednjem koraku se iz začetnih točk izdela robove: |
| 198 | | {{{ |
| 199 | | #!python |
| 200 | | # Definiranje geometrije |
| 201 | | aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4) |
| 202 | | aSegment1 = GC_MakeSegment(aPnt1 , aPnt2) |
| 203 | | aSegment2 = GC_MakeSegment(aPnt4 , aPnt5) |
| 204 | | |
| 205 | | # Definiranje topologije |
| 206 | | aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value()) |
| 207 | | aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value()) |
| 208 | | aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value()) |
| 209 | | }}} |
| 210 | | === Povezovanje robnih elementov v mreže === |
| 211 | | Robne elemente se v nadaljevanju združi v mrežo. |
| 212 | | {{{ |
| 213 | | #!python |
| 214 | | # Izdelava mreže |
| 215 | | aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge()) |
| 216 | | }}} |
| 217 | | === Uporaba funkcij za izdelavo objektov v prostoru === |
| 218 | | {{{ |
| 219 | | #!python |
| 220 | | # Izdelava celotnega profila - mirror |
| 221 | | xAxis = gp_OX() |
| 222 | | aTrsf = gp_Trsf() |
| 223 | | aTrsf.SetMirror(xAxis) |
| 224 | | aBRepTrsf = BRepBuilderAPI_Transform(aWire.Shape() , aTrsf) |
| 225 | | aMirroredShape = aBRepTrsf.Shape() |
| 226 | | aMirroredWire = TopoDS_wire(aMirroredShape) |
| 227 | | mkWire = BRepBuilderAPI_MakeWire() |
| 228 | | mkWire.Add(aWire.Wire()) |
| 229 | | mkWire.Add(aMirroredWire) |
| 230 | | myWireProfile = mkWire.Wire() |
| 231 | | |
| 232 | | # Telo: Iz profila se izdela telo (Funkcija izvleka 3D) |
| 233 | | myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile) |
| 234 | | aPrismVec = gp_Vec(0 , 0 , myHeight) |
| 235 | | myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face() , aPrismVec) |
| 236 | | }}} |
| 237 | | |
| 238 | | === Risanje geometrijskih primitivov === |
| 239 | | V OCC že obstajajo funkcije za izdelavo geometrijskih primitivov (kocka, valj,...), kar je prikazano na spodnjem primeru. |
| 240 | | {{{ |
| 241 | | #!python |
| 242 | | from OCC.Display.SimpleGui import * |
| 243 | | from OCC.BRepPrimAPI import * |
| 244 | | |
| 245 | | display, start_display, add_menu, add_function_to_menu = init_display() |
| 246 | | my_box = BRepPrimAPI_MakeBox(10.,20.,30.).Shape() |
| 247 | | # ali my_cylinder = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , myNeckHeight), kjer so spremenljivke že preddefinirane |
| 248 | | |
| 249 | | display.DisplayShape(my_box) # ali display.DisplayShape(my_cylinder) |
| 250 | | start_display() |
| 251 | | }}} |
| 252 | | === Izdelava primera Bottle z uporabo programskega jezika Python in knjižnice OCC === |
| 253 | | Naslednji primer prikazuje izdelavo primera BottleCAD. Podrobnejši razdelek posameznih delov programske kode dobimo na [[http://trac.lecad.si/vaje/wiki/OpenCascade|MakeBottleCAD(C++)]]. |
| 254 | | {{{ |
| 255 | | #!python |
| 256 | | ##Copyright 2011 Simon Kulovec (simon.kulovec@lecad.si) |
| 257 | | ##Example: MakeCADBottle |
| 258 | | ##This file is part of pythonOCC. |
| 259 | | |
| 260 | | ## Importanje različnih knjižnic |
| 261 | | |
| 262 | | # Uporabniški vmesnik GUI |
| 263 | | from OCC.Display.SimpleGui import * |
| 264 | | |
| 265 | | # OpenCascade |
| 266 | | from OCC.gp import * |
| 267 | | from OCC.TopoDS import * |
| 268 | | from OCC.GC import * |
| 269 | | from OCC.BRepBuilderAPI import * |
| 270 | | from OCC.BRepPrimAPI import * |
| 271 | | from OCC.BRepFilletAPI import * |
| 272 | | from OCC.BRepAlgoAPI import * |
| 273 | | from OCC.Utils.Topology import * |
| 274 | | from OCC.Geom import * |
| 275 | | from OCC.Geom2d import * |
| 276 | | from OCC.GCE2d import * |
| 277 | | from OCC.BRep import * |
| 278 | | from OCC.BRepLib import * |
| 279 | | from OCC.BRepOffsetAPI import * |
| 280 | | from OCC.TopTools import * |
| 281 | | from OCC.TopAbs import * |
| 282 | | from OCC.TopExp import * |
| 283 | | |
| 284 | | import math |
| 285 | | |
| 286 | | def show_bottle(aRes): |
| 287 | | display.EraseAll() |
| 288 | | print dir(display) |
| 289 | | display.DisplayShape(aRes) |
| 290 | | |
| 291 | | def define_points(myWidth, myThickness, myHeight): |
| 292 | | #Definiranje začetnih točk |
| 293 | | aPnt1 = gp_Pnt(-myWidth / 2. , 0 , 0) |
| 294 | | aPnt2 = gp_Pnt(-myWidth / 2. , -myThickness / 4. , 0) |
| 295 | | aPnt3 = gp_Pnt(0 , -myThickness / 2. , 0) |
| 296 | | aPnt4 = gp_Pnt(myWidth / 2. , -myThickness / 4. , 0) |
| 297 | | aPnt5 = gp_Pnt(myWidth / 2. , 0 , 0) |
| 298 | | |
| 299 | | #Definiranje geometrije |
| 300 | | aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3 ,aPnt4) |
| 301 | | aSegment1 = GC_MakeSegment(aPnt1 , aPnt2) |
| 302 | | aSegment2 = GC_MakeSegment(aPnt4 , aPnt5) |
| 303 | | |
| 304 | | #Definiranje topologije |
| 305 | | aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value()) |
| 306 | | aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value()) |
| 307 | | aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value()) |
| 308 | | aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge() , aEdge2.Edge() ,aEdge3.Edge()) |
| 309 | | |
| 310 | | #Izdelava celotnega profila - mirror |
| 311 | | xAxis = gp_OX() |
| 312 | | aTrsf = gp_Trsf() |
| 313 | | aTrsf.SetMirror(xAxis) |
| 314 | | aBRepTrsf = BRepBuilderAPI_Transform(aWire.Shape() , aTrsf) |
| 315 | | aMirroredShape = aBRepTrsf.Shape() |
| 316 | | aMirroredWire = TopoDS_wire(aMirroredShape) |
| 317 | | mkWire = BRepBuilderAPI_MakeWire() |
| 318 | | mkWire.Add(aWire.Wire()) |
| 319 | | mkWire.Add(aMirroredWire) |
| 320 | | myWireProfile = mkWire.Wire() |
| 321 | | |
| 322 | | # Telo: Iz profila se izdela telo |
| 323 | | myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile) |
| 324 | | aPrismVec = gp_Vec(0 , 0 , myHeight) |
| 325 | | myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face() , aPrismVec) |
| 326 | | |
| 327 | | # Telo: Dodamo zaokrožitve (fillet) |
| 328 | | mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape()) |
| 329 | | topology_traverser = Topo(myBody.Shape()) |
| 330 | | for aEdge in topology_traverser.edges(): |
| 331 | | mkFillet.Add(myThickness / 12. , aEdge) |
| 332 | | myBody = mkFillet.Shape() |
| 333 | | |
| 334 | | #Dodajanje grla na steklenico |
| 335 | | neckLocation = gp_Pnt(0, 0, myHeight) |
| 336 | | neckNormal = gp_DZ() |
| 337 | | neckAx2 = gp_Ax2(neckLocation, neckNormal) |
| 338 | | |
| 339 | | myNeckRadius = myThickness / 4 |
| 340 | | myNeckHeight = myHeight / 10 |
| 341 | | |
| 342 | | mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2 , myNeckRadius , \ |
| 343 | | myNeckHeight) |
| 344 | | myNeck = mkCylinder.Shape(); |
| 345 | | |
| 346 | | myBody = BRepAlgoAPI_Fuse(myBody, myNeck) |
| 347 | | |
| 348 | | # Izdelava votle steklenice |
| 349 | | faceToRemove = None |
| 350 | | zMax = -1; |
| 351 | | t = Topo(myBody.Shape()) |
| 352 | | k=1 |
| 353 | | for aFace in t.faces(): |
| 354 | | |
| 355 | | aSurface = BRep_Tool().Surface(aFace) |
| 356 | | |
| 357 | | if aSurface.GetObject().IsInstance('Geom_Plane'): |
| 358 | | aPlane = Handle_Geom_Plane().DownCast(aSurface).GetObject() |
| 359 | | aPnt = aPlane.Location() |
| 360 | | aZ = aPnt.Z() |
| 361 | | if aZ>zMax: |
| 362 | | faceToRemove = aFace |
| 363 | | |
| 364 | | facesToRemove = TopTools_ListOfShape() |
| 365 | | facesToRemove.Append(faceToRemove) |
| 366 | | myBody = BRepOffsetAPI_MakeThickSolid(myBody.Shape() , facesToRemove , \ |
| 367 | | -myThickness/50 , 1.e-3) |
| 368 | | |
| 369 | | # Threading : Create Surfaces |
| 370 | | aCyl1 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 0.99) |
| 371 | | aCyl2 = Geom_CylindricalSurface(gp_Ax3(neckAx2) , myNeckRadius * 1.05) |
| 372 | | |
| 373 | | # Threading : Define 2D Curves |
| 374 | | aPnt = gp_Pnt2d(2. * 3.141592 , myNeckHeight / 2.) |
| 375 | | aDir = gp_Dir2d(2. * 3.141592 , myNeckHeight / 4.) |
| 376 | | aAx2d = gp_Ax2d(aPnt , aDir) |
| 377 | | |
| 378 | | aMajor = 2. * 3.141592 |
| 379 | | aMinor = myNeckHeight / 10. |
| 380 | | |
| 381 | | anEllipse1 = Geom2d_Ellipse(aAx2d , aMajor , aMinor) |
| 382 | | anEllipse2 = Geom2d_Ellipse(aAx2d , aMajor , aMinor / 4) |
| 383 | | |
| 384 | | aArc2 = Geom2d_TrimmedCurve(anEllipse1.GetHandle() , 3.141592, 0.) |
| 385 | | aArc1 = Geom2d_TrimmedCurve(anEllipse2.GetHandle() , 3.141592, 0.) |
| 386 | | |
| 387 | | anEllipsePnt2 = anEllipse1.Value(0.) |
| 388 | | anEllipsePnt1 = anEllipse1.Value(3.141592) |
| 389 | | |
| 390 | | aSegment = GCE2d_MakeSegment(anEllipsePnt1 , anEllipsePnt2) |
| 391 | | |
| 392 | | # Threading : Build Edges and Wires |
| 393 | | aEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(aArc1.GetHandle() , aCyl1.GetHandle()) |
| 394 | | aEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment.Value() , aCyl1.GetHandle()) |
| 395 | | aEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(aArc2.GetHandle() , aCyl2.GetHandle()) |
| 396 | | aEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value() , aCyl2.GetHandle()) |
| 397 | | print dir(aEdge1OnSurf1) |
| 398 | | threadingWire1 = BRepBuilderAPI_MakeWire(aEdge1OnSurf1.Edge() , aEdge2OnSurf1.Edge()) |
| 399 | | threadingWire2 = BRepBuilderAPI_MakeWire(aEdge1OnSurf2.Edge() , aEdge2OnSurf2.Edge()) |