def __init__(self, *args): if len(args) == 3: fV = gp_Vec(*args) elif len(args) == 2: fV = gp_Vec(*args, 0) elif len(args) == 1: if isinstance(args[0], Vector): fV = gp_Vec(args[0].wrapped.XYZ()) elif isinstance(args[0], (tuple, list)): arg = args[0] if len(arg) == 3: fV = gp_Vec(*arg) elif len(arg) == 2: fV = gp_Vec(*arg, 0) elif isinstance(args[0], (gp_Vec, gp_Pnt, gp_Dir)): fV = gp_Vec(args[0].XYZ()) elif isinstance(args[0], gp_XYZ): fV = gp_Vec(args[0]) else: raise TypeError("Expected three floats, OCC gp_, or 3-tuple") elif len(args) == 0: fV = gp_Vec(0, 0, 0) else: raise TypeError("Expected three floats, OCC gp_, or 3-tuple") self._wrapped = fV
def transform(self, T: "Matrix") -> "Vector": # to gp_Pnt to obey cq transformation convention (in OCP.vectors do not translate) pnt = self.toPnt() pnt_t = pnt.Transformed(T.wrapped.Trsf()) return Vector(gp_Vec(pnt_t.XYZ()))
def testLocation(self): # Vector loc1 = Location(Vector(0, 0, 1)) T = loc1.wrapped.Transformation().TranslationPart() self.assertTupleAlmostEquals((T.X(), T.Y(), T.Z()), (0, 0, 1), 6) # rotation + translation loc2 = Location(Vector(0, 0, 1), Vector(0, 0, 1), 45) angle = loc2.wrapped.Transformation().GetRotation().GetRotationAngle() * RAD2DEG self.assertAlmostEqual(45, angle) # gp_Trsf T = gp_Trsf() T.SetTranslation(gp_Vec(0, 0, 1)) loc3 = Location(T) assert ( loc1.wrapped.Transformation().TranslationPart().Z() == loc3.wrapped.Transformation().TranslationPart().Z() ) # Test creation from the OCP.gp.gp_Trsf object loc4 = Location(gp_Trsf()) self.assertTupleAlmostEquals(loc4.toTuple()[0], (0, 0, 0), 7) self.assertTupleAlmostEquals(loc4.toTuple()[1], (0, 0, 0), 7) # Test error handling on creation with self.assertRaises(TypeError): Location((0, 0, 1)) with self.assertRaises(TypeError): Location("xy_plane")
def testVectorConstructors(self): v1 = Vector(1, 2, 3) v2 = Vector((1, 2, 3)) v3 = Vector(gp_Vec(1, 2, 3)) v4 = Vector([1, 2, 3]) v5 = Vector(gp_XYZ(1, 2, 3)) for v in [v1, v2, v3, v4, v5]: self.assertTupleAlmostEquals((1, 2, 3), v.toTuple(), 4) v6 = Vector((1, 2)) v7 = Vector([1, 2]) v8 = Vector(1, 2) for v in [v6, v7, v8]: self.assertTupleAlmostEquals((1, 2, 0), v.toTuple(), 4) v9 = Vector() self.assertTupleAlmostEquals((0, 0, 0), v9.toTuple(), 4) v9.x = 1.0 v9.y = 2.0 v9.z = 3.0 self.assertTupleAlmostEquals((1, 2, 3), (v9.x, v9.y, v9.z), 4) with self.assertRaises(TypeError): Vector("vector") with self.assertRaises(TypeError): Vector(1, 2, 3, 4)
def point_in_plane_cost( m1: gp_Pnt, m2: gp_Pln, t1: gp_Trsf, t2: gp_Trsf, val: Optional[float] = None, ) -> float: val = 0 if val is None else val m2_located = m2.Transformed(t2) # offset in the plane's normal direction by val: m2_located.Translate(gp_Vec(m2_located.Axis().Direction()).Multiplied(val)) return m2_located.Distance(m1.Transformed(t1))
def tessellate(self): self.vertices = [] self.triangles = [] self.normals = [] # global buffers p_buf = gp_Pnt() n_buf = gp_Vec() loc_buf = TopLoc_Location() offset = -1 # every line below is selected for performance. Do not introduce functions to "beautify" the code for face in get_faces(self.shape): if face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED: i1, i2 = 2, 1 else: i1, i2 = 1, 2 internal = face.Orientation() == TopAbs_Orientation.TopAbs_INTERNAL poly = BRep_Tool.Triangulation_s(face, loc_buf) if poly is not None: Trsf = loc_buf.Transformation() # add vertices flat = [] for i in range(1, poly.NbNodes() + 1): flat.extend(poly.Node(i).Transformed(Trsf).Coord()) self.vertices.extend(flat) # add triangles flat = [] for i in range(1, poly.NbTriangles() + 1): coord = poly.Triangle(i).Get() flat.extend((coord[0] + offset, coord[i1] + offset, coord[i2] + offset)) self.triangles.extend(flat) # add normals if poly.HasUVNodes(): prop = BRepGProp_Face(face) flat = [] for i in range(1, poly.NbNodes() + 1): u, v = poly.UVNode(i).Coord() prop.Normal(u, v, p_buf, n_buf) if n_buf.SquareMagnitude() > 0: n_buf.Normalize() flat.extend(n_buf.Reverse().Coord( ) if internal else n_buf.Coord()) self.normals.extend(flat) offset += poly.NbNodes()
def _build_transform( self, x: float, y: float, z: float, a: float, b: float, c: float ) -> gp_Trsf: rv = gp_Trsf() m = a ** 2 + b ** 2 + c ** 2 rv.SetRotation( gp_Quaternion( 2 * a / (m + 1), 2 * b / (m + 1), 2 * c / (m + 1), (1 - m) / (m + 1), ) ) rv.SetTranslationPart(gp_Vec(x, y, z)) return rv
def testLocation(self): # Vector loc1 = Location(Vector(0, 0, 1)) T = loc1.wrapped.Transformation().TranslationPart() self.assertTupleAlmostEquals((T.X(), T.Y(), T.Z()), (0, 0, 1), 6) # rotation + translation loc2 = Location(Vector(0, 0, 1), Vector(0, 0, 1), 45) angle = loc2.wrapped.Transformation().GetRotation().GetRotationAngle( ) * RAD2DEG self.assertAlmostEqual(45, angle) # gp_Trsf T = gp_Trsf() T.SetTranslation(gp_Vec(0, 0, 1)) loc3 = Location(T) assert (loc1.wrapped.Transformation().TranslationPart().Z() == loc3.wrapped.Transformation().TranslationPart().Z())
def tessellate(self): self.vertices = array("f") self.triangles = array("f") self.normals = array("f") # global buffers p_buf = gp_Pnt() n_buf = gp_Vec() loc_buf = TopLoc_Location() offset = -1 # every line below is selected for performance. Do not introduce functions to "beautify" the code for face in get_faces(self.shape): if face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED: i1, i2 = 2, 1 else: i1, i2 = 1, 2 internal = face.Orientation() == TopAbs_Orientation.TopAbs_INTERNAL poly = BRep_Tool.Triangulation_s(face, loc_buf) if poly is not None: Trsf = loc_buf.Transformation() # add vertices # [node.Transformed(Trsf).Coord() for node in poly.Nodes()] is 5-8 times slower! items = poly.Nodes() coords = [items.Value(i).Transformed(Trsf).Coord() for i in range(items.Lower(), items.Upper() + 1)] flat = [] for coord in coords: flat += coord self.vertices.extend(flat) # add triangles items = poly.Triangles() coords = [items.Value(i).Get() for i in range(items.Lower(), items.Upper() + 1)] flat = [] for coord in coords: flat += (coord[0] + offset, coord[i1] + offset, coord[i2] + offset) self.triangles.extend(flat) # add normals if poly.HasUVNodes(): def extract(uv0, uv1): prop.Normal(uv0, uv1, p_buf, n_buf) if n_buf.SquareMagnitude() > 0: n_buf.Normalize() return n_buf.Reverse().Coord() if internal else n_buf.Coord() prop = BRepGProp_Face(face) items = poly.UVNodes() uvs = [items.Value(i).Coord() for i in range(items.Lower(), items.Upper() + 1)] flat = [] for uv1, uv2 in uvs: flat += extract(uv1, uv2) self.normals.extend(flat) offset += poly.NbNodes()
def tq_to_loc(t, q): T = gp_Trsf() Q = gp_Quaternion(*q) V = gp_Vec(*t) T.SetTransformation(Q, V) return TopLoc_Location(T)
def tessellate(shape, tolerance: float, angularTolerance: float = 0.1): # Remove previous mesh data BRepTools.Clean_s(shape) triangulated = BRepTools.Triangulation_s(shape, tolerance) if not triangulated: # this will add mesh data to the shape and prevent calculating an exact bounding box after this call BRepMesh_IncrementalMesh(shape, tolerance, True, angularTolerance) vertices = [] triangles = [] normals = [] offset = 0 for face in get_faces(shape): loc = TopLoc_Location() poly = BRep_Tool.Triangulation_s(face, loc) Trsf = loc.Transformation() reverse = face.Orientation() == TopAbs_Orientation.TopAbs_REVERSED internal = face.Orientation() == TopAbs_Orientation.TopAbs_INTERNAL # add vertices if poly is not None: vertices += [(v.X(), v.Y(), v.Z()) for v in (v.Transformed(Trsf) for v in poly.Nodes())] # add triangles triangles += [( t.Value(1) + offset - 1, t.Value(3 if reverse else 2) + offset - 1, t.Value(2 if reverse else 3) + offset - 1, ) for t in poly.Triangles()] # add normals if poly.HasUVNodes(): prop = BRepGProp_Face(face) uvnodes = poly.UVNodes() for uvnode in uvnodes: p = gp_Pnt() n = gp_Vec() prop.Normal(uvnode.X(), uvnode.Y(), p, n) if n.SquareMagnitude() > 0: n.Normalize() if internal: n.Reverse() normals.append((n.X(), n.Y(), n.Z())) offset += poly.NbNodes() if not triangulated: # Remove the mesh data again BRepTools.Clean_s(shape) return ( np.asarray(vertices, dtype=np.float32), np.asarray(triangles, dtype=np.uint32), np.asarray(normals, dtype=np.float32), )
def getSignedAngle(self, v: "Vector") -> float: return self.wrapped.AngleWithRef(v.wrapped, gp_Vec(0, 0, -1))