updated to modern VTK
[engrid-github.git] / src / pymodules / EngitsPyOcc.py
blob55985d759749a8349e1860c312073f0fb91b2365
1 #!/usr/bin/python
2 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 # + +
4 # + This file is part of enGrid. +
5 # + +
6 # + Copyright 2008-2014 enGits GmbH +
7 # + +
8 # + enGrid is free software: you can redistribute it and/or modify +
9 # + it under the terms of the GNU General Public License as published by +
10 # + the Free Software Foundation, either version 3 of the License, or +
11 # + (at your option) any later version. +
12 # + +
13 # + enGrid is distributed in the hope that it will be useful, +
14 # + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 # + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 # + GNU General Public License for more details. +
17 # + +
18 # + You should have received a copy of the GNU General Public License +
19 # + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 # + +
21 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 from OCC.Utils import Common, Construct
24 from OCC.StlAPI import *
25 from OCC.DataExchange.STEP import *
26 from OCC.DataExchange.IGES import *
27 from OCC.BRepPrimAPI import *
28 from OCC.BRepBuilderAPI import *
30 import sys
31 import math
33 def angle3D(ux, uy, uz, vx, vy, vz):
34 ptot2 = (ux**2 + uy**2 + uz**2)*(vx**2 + vy**2 + vz**2)
35 if ptot2 > 0:
36 arg = (ux*vx + uy*vy + uz*vz)/math.sqrt(ptot2)
37 if arg > 1.0:
38 arg = 1.0
39 if arg < -1.0:
40 arg = -1.0
41 return math.degrees(math.acos(arg))
42 return 0.0
45 def partial_cylinder(x1, y1, z1, x2, y2, z2, radius, angle):
46 L = math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2)
47 direction = Common.gp_Dir((x2 - x1)/L, (y2 - y1)/L, (z2 - z1)/L)
48 axis = Common.gp_Ax2(Common.gp_Pnt(x1, y1, z1), direction)
49 if angle < 360:
50 angle = angle*math.pi/180
51 shape = BRepPrimAPI.BRepPrimAPI_MakeCylinder(axis, radius, L, angle).Shape()
52 else:
53 shape = BRepPrimAPI.BRepPrimAPI_MakeCylinder(axis, radius, L).Shape()
54 return shape
57 def cylinder(x1, y1, z1, x2, y2, z2, radius):
58 return partial_cylinder(x1, y1, z1, x2, y2, z2, radius, 360)
61 def box(x1, y1, z1, x2, y2, z2):
62 return BRepPrimAPI.BRepPrimAPI_MakeBox(Common.gp_Pnt(x1, y1, z1), Common.gp_Pnt(x2, y2, z2)).Shape()
65 def rotate(shape, x1, y1, z1, x2, y2, z2, angle):
66 L = math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2)
67 direction = Common.gp_Dir((x2 - x1)/L, (y2 - y1)/L, (z2 - z1)/L)
68 axis = Common.gp_Ax1(Common.gp_Pnt(x1, y1, z1), direction)
69 return Construct.rotate(shape, axis, angle)
72 def rotate_x(shape, x, y, z, angle):
73 return rotate(shape, x, y, z, x + 1, y, z, angle)
76 def rotate_x0(shape, angle):
77 return rotate(shape, 0, 0, 0, 1, 0, 0, angle)
80 def rotate_y(shape, x, y, z, angle):
81 return rotate(shape, x, y, z, x, y + 1, z, angle)
84 def rotate_y0(shape, angle):
85 return rotate(shape, 0, 0, 0, 0, 1, 0, angle)
88 def rotate_z(shape, x, y, z, angle):
89 return rotate(shape, x, y, z, x, y, z + 1, angle)
92 def rotate_z0(shape, angle):
93 return rotate(shape, 0, 0, 0, 0, 0, 1, angle)
96 def cut(shape1, shape2):
97 return Construct.boolean_cut(shape1, shape2)
100 def join(shape1, shape2):
101 return Construct.boolean_fuse(shape1, shape2)
104 def intersect(shape1, shape2):
105 cut_shape = cut(shape1, shape2)
106 return cut(shape1, cut_shape)
109 def move(shape, dx, dy, dz):
110 return Construct.translate_topods_from_vector(shape, Common.gp_Vec(dx, dy, dz))
113 def move_x(shape, dx):
114 return Construct.translate_topods_from_vector(shape, Common.gp_Vec(dx, 0, 0))
117 def move_y(shape, dy):
118 return Construct.translate_topods_from_vector(shape, Common.gp_Vec(0, dy, 0))
121 def move_z(shape, dz):
122 return Construct.translate_topods_from_vector(shape, Common.gp_Vec(0, 0, dz))
125 def cone(x1, y1, z1, x2, y2, z2, R1, R2):
126 L = math.sqrt((x2-x1)**2 + (y2-y1)**2 + (z2-z1)**2)
127 angle = angle3D(0, 0, 1, x2-x1, y2-y1, z2-z1)
128 shape = BRepPrimAPI.BRepPrimAPI_MakeCone(R1, R2, L).Shape()
129 l = math.sqrt((x2-x1)**2 + (y2-y1)**2)
130 if l/L > 1e-4:
131 shape = rotate(shape, 0, 0, 0, y1-y2, x2-x1, 0, angle)
132 return move(shape, x1, y1, z1)
135 def sphere(x, y, z, R):
136 shape = BRepPrimAPI.BRepPrimAPI_MakeSphere(R).Shape()
137 return move(shape, x, y, z)
140 def nose(x1, y1, z1, x2, y2, z2, R, r):
141 nx = x2 - x1
142 ny = y2 - y1
143 nz = z2 - z1
144 H = math.sqrt(nx*nx + ny*ny + nz*nz)
145 nx /= H
146 ny /= H
147 nz /= H
148 xe = R;
149 ye = r - H
150 scal = 1
151 a1 = 0
152 a2 = 0.5*math.pi
153 xt = 0
154 yt = 0
155 count = 0
156 while math.fabs(scal) > 1e-6 and count < 1000:
157 a = 0.5*(a1 + a2)
158 xt = r*math.cos(a)
159 yt = r*math.sin(a)
160 vx = xt - xe
161 vy = yt - ye
162 L = math.sqrt(vx*vx + vy*vy)
163 scal = (vx*xt + vy*yt)/(L*r)
164 if scal > 0:
165 a2 = a
166 else:
167 a1 = a
168 count += 1
169 xs = x2 - r*nx
170 ys = y2 - r*ny
171 zs = z2 - r*nz
172 xc = xs + yt*nx
173 yc = ys + yt*ny
174 zc = zs + yt*nz
176 cone_shape = cone(x1, y1, z1, xc, yc, zc, R, xt)
177 sphere_shape = sphere(xs, ys, zs, r)
179 return join(cone_shape, sphere_shape)
182 def scale(shape, x, y, z, factor):
183 return Construct.scale(shape, Common.gp_Pnt(x,y,z), factor)
187 #The prototype for the BRepBuilderAPI_MakeSolid method is (just type help(BRepBuilderAPI_MakeSolid)):
188 #__init__(self, TopoDS_CompSolid S) -> BRepBuilderAPI_MakeSolid
189 #__init__(self, TopoDS_Shell S) -> BRepBuilderAPI_MakeSolid
190 #__init__(self, TopoDS_Shell S1, TopoDS_Shell S2) -> BRepBuilderAPI_MakeSolid
191 #__init__(self, TopoDS_Shell S1, TopoDS_Shell S2, TopoDS_Shell S3) -> BRepBuilderAPI_MakeSolid
192 #__init__(self, TopoDS_Solid So) -> BRepBuilderAPI_MakeSolid
193 #__init__(self, TopoDS_Solid So, TopoDS_Shell S) -> BRepBuilderAPI_MakeSolid
195 #That is to say, you first have to convert the sewed shape to a Shell.
197 #Here is your code corrected:
199 #sewing = BRepBuilderAPI_Sewing()
201 #for i in range(14):
202 #sewing.Add(faces[i])
204 #sewing.Perform()
205 #sewed_shape = sewing.SewedShape()
206 ## It works fine until here, and I can display the shell
208 #from OCC.TopoDS import *
209 #tds = TopoDS()
211 #solid = BRepBuilderAPI_MakeSolid(tds.Shell(sewed_shape))
213 def solid(faces):
214 sewing = BRepBuilderAPI_Sewing()
215 for face in faces:
216 pts = []
217 for node in face:
218 pts.append(Common.gp_Pnt(node[0], node[1], node[2]))
219 try:
220 sewing.Add(Construct.make_face(Construct.make_closed_polygon(pts)))
221 except AssertionError:
222 print pts
223 exit(1)
224 sewing.Perform()
225 sewed_shape = sewing.SewedShape()
226 return sewed_shape
227 #tds = Construct.TopoDS()
228 #return BRepBuilderAPI_MakeSolid(tds.Shell(sewed_shape))
233 def write_stl(shape, file_name, precision):
234 writer = StlAPI_Writer()
235 writer.SetRelativeMode(True)
236 writer.SetCoefficient(precision)
237 writer.Write(shape, file_name)