-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from theRealSuperMario/splitter_demo_V2
Add unnecessarily detailed splitter demo
- Loading branch information
Showing
1 changed file
with
291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"source": [ | ||
"from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Splitter\n", | ||
"from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakePolygon\n", | ||
"from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox\n", | ||
"from OCC.Core.gp import gp_Pnt\n", | ||
"from OCC.Core import TopAbs\n", | ||
"\n", | ||
"from OCC.Display.WebGl.jupyter_renderer import JupyterRenderer\n", | ||
"from OCC.Core.BRep import BRep_Polygon3D\n", | ||
"from OCC.Core.TopExp import TopExp_Explorer\n", | ||
"\n", | ||
"from OCC.Core.BOPAlgo import BOPAlgo_Splitter" | ||
], | ||
"outputs": [], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"source": [ | ||
"# Define Polygon and perform split operation" | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 18, | ||
"source": [ | ||
"# See https://dev.opencascade.org/doc/overview/html/occt_user_guides__modeling_algos.html\n", | ||
"\n", | ||
"W = BRepBuilderAPI_MakePolygon()\n", | ||
"W.Add(gp_Pnt(-2, -2, 1))\n", | ||
"W.Add(gp_Pnt(-2, 2, 1))\n", | ||
"W.Add(gp_Pnt(2, 2, 1))\n", | ||
"W.Add(gp_Pnt(2, -2, 1))\n", | ||
"\n", | ||
"W.Close()\n", | ||
"\n", | ||
"# At this point, the polygon shape is a \"wire frame\"\n", | ||
"shape1_wire = W.Shape()\n", | ||
"print(\"Shape type of Polygon after .Close()\", shape1_wire.ShapeType)\n", | ||
"# in order to perform a split with the enture surface of the polygon, we have to convert the wire frame to a face\n", | ||
"shape1_face = BRepBuilderAPI_MakeFace(shape1_wire)\n", | ||
"print(\"Shape type of Face\", shape1_face.Shape().ShapeType)\n", | ||
"\n", | ||
"\n", | ||
"box = BRepPrimAPI_MakeBox(gp_Pnt(-0.25, 0, 0), gp_Pnt(0.25, 1, 2)).Shape()\n", | ||
"# section_shp = BRepAlgoAPI_Section(shape1_face.Shape(), wall)\n", | ||
"\n", | ||
"splitter = BOPAlgo_Splitter()\n", | ||
"splitter.SetNonDestructive(False)\n", | ||
"splitter.AddArgument(box) # arugment means object to cut\n", | ||
"splitter.AddTool(shape1_face.Shape()) # tool means arguments are cut by this\n", | ||
"splitter.Perform()\n", | ||
"\n", | ||
"result = splitter.Shape()\n", | ||
"\n", | ||
"\n", | ||
"rnd = JupyterRenderer()\n", | ||
"rnd.DisplayShape(result, render_edges=True)\n", | ||
"\n", | ||
"rnd.Display()" | ||
], | ||
"outputs": [ | ||
{ | ||
"output_type": "stream", | ||
"name": "stdout", | ||
"text": [ | ||
"Shape type of Polygon after .Close() <bound method TopoDS_Shape.ShapeType of <class 'TopoDS_Wire'>>\n", | ||
"Shape type of Face <bound method TopoDS_Shape.ShapeType of <class 'TopoDS_Face'>>\n" | ||
] | ||
}, | ||
{ | ||
"output_type": "display_data", | ||
"data": { | ||
"text/plain": [ | ||
"HBox(children=(VBox(children=(HBox(children=(Checkbox(value=True, description='Axes', layout=Layout(height='au…" | ||
], | ||
"application/vnd.jupyter.widget-view+json": { | ||
"version_major": 2, | ||
"version_minor": 0, | ||
"model_id": "92eb1c637b754e38b80468952ca150ac" | ||
} | ||
}, | ||
"metadata": {} | ||
} | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"source": [ | ||
"# Problem: the result is still a compound structure of the upper and lower half-box\n", | ||
"- This can be seen by inspecting the ``result.ShapeType`` property. It should read ``TopoDS_Compound``" | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 19, | ||
"source": [ | ||
"print(result.ShapeType)" | ||
], | ||
"outputs": [ | ||
{ | ||
"output_type": "stream", | ||
"name": "stdout", | ||
"text": [ | ||
"<bound method TopoDS_Shape.ShapeType of <class 'TopoDS_Compound'>>\n" | ||
] | ||
} | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"source": [ | ||
"# Decompose the split results\n", | ||
"* There are probably multiple ways to decompose the results of the split operation, but one was is to use the `TopExp_Explorer`." | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 20, | ||
"source": [ | ||
"exp = TopExp_Explorer()\n", | ||
"exp.Init(result, TopAbs.TopAbs_SOLID)\n", | ||
"\n", | ||
"sub_shapes = []\n", | ||
"while exp.More():\n", | ||
" sub_shapes.append(exp.Current())\n", | ||
" exp.Next()" | ||
], | ||
"outputs": [], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 131, | ||
"source": [ | ||
"\n", | ||
"rnd = JupyterRenderer()\n", | ||
"colors = [\"#DB0570\", \"#0506DB\"]\n", | ||
"for s,c in zip(sub_shapes, colors):\n", | ||
" rnd.DisplayShape(s, render_edges=True, shape_color=c)\n", | ||
"\n", | ||
"rnd.Display()" | ||
], | ||
"outputs": [ | ||
{ | ||
"output_type": "display_data", | ||
"data": { | ||
"text/plain": [ | ||
"HBox(children=(VBox(children=(HBox(children=(Checkbox(value=True, description='Axes', layout=Layout(height='au…" | ||
], | ||
"application/vnd.jupyter.widget-view+json": { | ||
"version_major": 2, | ||
"version_minor": 0, | ||
"model_id": "4185464ad0134a9597c10efd3747365b" | ||
} | ||
}, | ||
"metadata": {} | ||
} | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"source": [ | ||
"# Educational example: what if we used the wire frame shape rather than the face to perform the split.\n", | ||
"* We define the split frame at the center of the box surfaces\n", | ||
"* This does not cut the solid into two pieces, but rather cuts the surfaces into pieces.\n", | ||
"* As result, the explorer only returns a single solid.\n", | ||
"* The shape type of the result is `Solid` rather than `Compound`" | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 11, | ||
"source": [ | ||
"# See https://dev.opencascade.org/doc/overview/html/occt_user_guides__modeling_algos.html\n", | ||
"\n", | ||
"W = BRepBuilderAPI_MakePolygon()\n", | ||
"W.Add(gp_Pnt(-0.25, -0.25, 1))\n", | ||
"W.Add(gp_Pnt(0.25, -0.25, 1))\n", | ||
"W.Add(gp_Pnt(0.25, 0.25, 1))\n", | ||
"W.Add(gp_Pnt(-0.25, 0.25, 1))\n", | ||
"\n", | ||
"W.Close()\n", | ||
"\n", | ||
"# At this point, the polygon shape is a \"wire frame\"\n", | ||
"shape1_wire = W.Shape()\n", | ||
"print(\"Shape type of Polygon after .Close()\", shape1_wire.ShapeType)\n", | ||
"\n", | ||
"\n", | ||
"box = BRepPrimAPI_MakeBox(gp_Pnt(-0.25, -0.25, 0), gp_Pnt(0.25, 0.25, 2)).Shape()\n", | ||
"# section_shp = BRepAlgoAPI_Section(shape1_face.Shape(), wall)\n", | ||
"\n", | ||
"splitter = BOPAlgo_Splitter()\n", | ||
"splitter.SetNonDestructive(False)\n", | ||
"splitter.AddArgument(box) # arugment means object to cut\n", | ||
"splitter.AddTool(shape1_wire) # tool means arguments are cut by this\n", | ||
"splitter.Perform()\n", | ||
"\n", | ||
"result = splitter.Shape()\n", | ||
"print(\"Shape type of result\", result.ShapeType)\n", | ||
"\n", | ||
"\n", | ||
"exp = TopExp_Explorer()\n", | ||
"exp.Init(result, TopAbs.TopAbs_SOLID)\n", | ||
"\n", | ||
"sub_shapes = []\n", | ||
"while exp.More():\n", | ||
" sub_shapes.append(exp.Current())\n", | ||
" exp.Next()\n", | ||
"\n", | ||
"print(\"Sub shapes after split\", sub_shapes)\n", | ||
"\n", | ||
"\n", | ||
"rnd = JupyterRenderer()\n", | ||
"# rnd.DisplayShape(result, render_edges=True)\n", | ||
"rnd.DisplayShape(result, render_edges=True)\n", | ||
"\n", | ||
"rnd.Display()" | ||
], | ||
"outputs": [ | ||
{ | ||
"output_type": "stream", | ||
"name": "stdout", | ||
"text": [ | ||
"Shape type of Polygon after .Close() <bound method TopoDS_Shape.ShapeType of <class 'TopoDS_Wire'>>\n", | ||
"Shape type of result <bound method TopoDS_Shape.ShapeType of <class 'TopoDS_Solid'>>\n", | ||
"Sub shapes after split [<class 'TopoDS_Solid'>]\n" | ||
] | ||
}, | ||
{ | ||
"output_type": "display_data", | ||
"data": { | ||
"text/plain": [ | ||
"HBox(children=(VBox(children=(HBox(children=(Checkbox(value=True, description='Axes', layout=Layout(height='au…" | ||
], | ||
"application/vnd.jupyter.widget-view+json": { | ||
"version_major": 2, | ||
"version_minor": 0, | ||
"model_id": "c86e83a5565f4bc1bfeb2b24ecdab730" | ||
} | ||
}, | ||
"metadata": {} | ||
} | ||
], | ||
"metadata": {} | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"source": [], | ||
"outputs": [], | ||
"metadata": {} | ||
} | ||
], | ||
"metadata": { | ||
"orig_nbformat": 4, | ||
"language_info": { | ||
"name": "python", | ||
"version": "3.8.8", | ||
"mimetype": "text/x-python", | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"pygments_lexer": "ipython3", | ||
"nbconvert_exporter": "python", | ||
"file_extension": ".py" | ||
}, | ||
"kernelspec": { | ||
"name": "python3", | ||
"display_name": "Python 3.8.8 64-bit ('modugen-core': conda)" | ||
}, | ||
"interpreter": { | ||
"hash": "6460e2c7b7e871d9f5b01267be5926c0fb721727d5ff96e838bc764f1e614f64" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |