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