diff --git a/src/Mod/Draft/DraftVecUtils.py b/src/Mod/Draft/DraftVecUtils.py index 2939b35231..a819117552 100644 --- a/src/Mod/Draft/DraftVecUtils.py +++ b/src/Mod/Draft/DraftVecUtils.py @@ -724,10 +724,11 @@ def rounded(v,d=None): return Vector(round(v.x, p), round(v.y, p), round(v.z, p)) -def getPlaneRotation(u, v, w=None): +def getPlaneRotation(u, v, _ = None): """Return a rotation matrix defining the (u,v,w) coordinate system. The rotation matrix uses the elements from each vector. + `v` is adjusted to be perpendicular to `u` :: (u.x v.x w.x 0 ) R = (u.y v.y w.y 0 ) @@ -739,25 +740,26 @@ def getPlaneRotation(u, v, w=None): u : Base::Vector3 The first vector. v : Base::Vector3 - The second vector. - w : Base::Vector3, optional - The third vector. It defaults to `None`, in which case - it is calculated as the cross product of `u` and `v`. - :: - w = u.cross(v) - + Hint for the second vector. + _ : Ignored. For backwards compatibility + Returns ------- Base::Matrix4D The new rotation matrix defining a new coordinate system, - or `None` if `u`, or `v`, is `None`. + or `None` if `u` or `v` is `None` or + if `u` and `v` are parallel. """ if (not u) or (not v): return None - - if not w: - w = u.cross(v) - typecheck([(u, Vector), (v, Vector), (w, Vector)], "getPlaneRotation") + typecheck([(u, Vector), (v, Vector)], "getPlaneRotation") + u = Vector(u) + u.normalize() + w = u.cross(v) + if not w.Length: + return None + w.normalize() + v = w.cross(u) m = FreeCAD.Matrix(u.x, v.x, w.x, 0, u.y, v.y, w.y, 0, diff --git a/src/Mod/Draft/WorkingPlane.py b/src/Mod/Draft/WorkingPlane.py index 49fce472be..b4660c3860 100644 --- a/src/Mod/Draft/WorkingPlane.py +++ b/src/Mod/Draft/WorkingPlane.py @@ -863,7 +863,7 @@ class Plane: A placement, comprised of a `Base` (`Base::Vector3`), and a `Rotation` (`Base::Rotation`). """ - m = DraftVecUtils.getPlaneRotation(self.u, self.v, self.axis) + m = DraftVecUtils.getPlaneRotation(self.u, self.v) p = FreeCAD.Placement(m) # Arch active container if FreeCAD.GuiUp: @@ -892,17 +892,10 @@ class Plane: and a `Rotation` (`Base::Rotation`). """ if rotated: - m = FreeCAD.Matrix( - self.u.x, self.axis.x, -self.v.x, self.position.x, - self.u.y, self.axis.y, -self.v.y, self.position.y, - self.u.z, self.axis.z, -self.v.z, self.position.z, - 0.0, 0.0, 0.0, 1.0) + m = DraftVecUtils.getPlaneRotation(self.u, self.v) else: - m = FreeCAD.Matrix( - self.u.x, self.v.x, self.axis.x, self.position.x, - self.u.y, self.v.y, self.axis.y, self.position.y, - self.u.z, self.v.z, self.axis.z, self.position.z, - 0.0, 0.0, 0.0, 1.0) + m = DraftVecUtils.getPlaneRotation(self.u, self.v) + m.move(self.position) p = FreeCAD.Placement(m) # Arch active container if based on App Part # if FreeCAD.GuiUp: diff --git a/src/Mod/Draft/draftviewproviders/view_dimension.py b/src/Mod/Draft/draftviewproviders/view_dimension.py index 6b4f0acbad..04dad66482 100644 --- a/src/Mod/Draft/draftviewproviders/view_dimension.py +++ b/src/Mod/Draft/draftviewproviders/view_dimension.py @@ -496,7 +496,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase): u = u.negative() v2 = norm.cross(u) - _plane_rot = DraftVecUtils.getPlaneRotation(u, v2, norm) + _plane_rot = DraftVecUtils.getPlaneRotation(u, v2) rot2 = App.Placement(_plane_rot).Rotation.Q self.trans1.rotation.setValue((rot2[0], rot2[1], rot2[2], rot2[3])) @@ -507,7 +507,7 @@ class ViewProviderLinearDimension(ViewProviderDimensionBase): u3 = self.p1 - self.p2 u3.normalize() v3 = norm.cross(u3) - _plane_rot = DraftVecUtils.getPlaneRotation(u3, v3, norm) + _plane_rot = DraftVecUtils.getPlaneRotation(u3, v3) rot3 = App.Placement(_plane_rot).Rotation.Q self.transExtOvershoot1.rotation.setValue((rot3[0], rot3[1], rot3[2], rot3[3])) @@ -1046,8 +1046,8 @@ class ViewProviderAngularDimension(ViewProviderDimensionBase): v1 = w1.cross(u1) v2 = w2.cross(u2) - _plane_rot_1 = DraftVecUtils.getPlaneRotation(u1, v1, w1) - _plane_rot_2 = DraftVecUtils.getPlaneRotation(u2, v2, w2) + _plane_rot_1 = DraftVecUtils.getPlaneRotation(u1, v1) + _plane_rot_2 = DraftVecUtils.getPlaneRotation(u2, v2) q1 = App.Placement(_plane_rot_1).Rotation.Q q2 = App.Placement(_plane_rot_2).Rotation.Q @@ -1062,7 +1062,7 @@ class ViewProviderAngularDimension(ViewProviderDimensionBase): u3 = ray.cross(norm).normalize() v3 = norm.cross(u3) - _plane_rot_3 = DraftVecUtils.getPlaneRotation(u3, v3, norm) + _plane_rot_3 = DraftVecUtils.getPlaneRotation(u3, v3) r = App.Placement(_plane_rot_3).Rotation offset = r.multVec(App.Vector(0, 1, 0)) diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index e9289eb182..432d23bdd7 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -1143,7 +1143,7 @@ def drawEllipse(ellipse, forceShape=False): x = majv.normalize() z = vec(ellipse.extrusion).normalize() y = z.cross(x) - m = DraftVecUtils.getPlaneRotation(x, y, z) + m = DraftVecUtils.getPlaneRotation(x, y) pl = FreeCAD.Placement(m) pl.move(c) if (dxfCreateDraft or dxfCreateSketch) and (not forceShape):