def test_Fitting(self): # Collinear points should not define a plane. a = Gf.Vec3d(0, 0, 0) b = Gf.Vec3d(1, 0, 0) c = Gf.Vec3d(2, 0, 0) self.assertIsNone(Gf.FitPlaneToPoints([a, b, c]), err("collinear")) # Cannot fit plane to 2 or fewer points. with self.assertRaises(Tf.ErrorException): Gf.FitPlaneToPoints([a, b]) # Perfect fit (normal should be parallel to Z-axis, but OK if opposite # direction). c = Gf.Vec3d(0, 1, 0) p = Gf.FitPlaneToPoints([a, b, c]) self.assertAlmostEqual(Gf.Dot(p.GetNormal(), Gf.Vec3d.ZAxis()), 1.0, msg=err("normal1")) self.assertAlmostEqual(p.GetDistanceFromOrigin(), 0.0, msg=err("distance1")) # Try the same plane but with non-unit vectors. b = Gf.Vec3d(1.5, 0, 0) c = Gf.Vec3d(0, 3.2, 0) p = Gf.FitPlaneToPoints([a, b, c]) self.assertAlmostEqual(Gf.Dot(p.GetNormal(), Gf.Vec3d.ZAxis()), 1.0, msg=err("normal2")) self.assertAlmostEqual(p.GetDistanceFromOrigin(), 0.0, msg=err("distance2")) # Try a more complicated plane. p1 = Gf.Plane(Gf.Vec4d(3, 4, 0, 5)) # equation constructor a = p1.Project(Gf.Vec3d(2, 3, 6)) b = p1.Project(Gf.Vec3d(34, -2, 2)) c = p1.Project(Gf.Vec3d(-3, 7, -8)) d = p1.Project(Gf.Vec3d(4, 1, 1)) e = p1.Project(Gf.Vec3d(87, 67, 92)) p2 = Gf.FitPlaneToPoints([a, b, c]) self.assertAlmostEqual( Gf.Dot(p1.GetNormal(), p2.GetNormal()), 1.0, msg=err("p2 normal parallel to p1")) self.assertAlmostEqual( p1.GetDistanceFromOrigin(), p2.GetDistanceFromOrigin(), msg=err("p2 distance equals p1")) p3 = Gf.FitPlaneToPoints([a, b, c, d, e]) self.assertAlmostEqual( Gf.Dot(p1.GetNormal(), p3.GetNormal()), 1.0, msg=err("p3 normal parallel to p1")) self.assertAlmostEqual( p1.GetDistanceFromOrigin(), p3.GetDistanceFromOrigin(), msg=err("p3 distance equals p1")) # Try fitting points that don't form a perfect plane. # This roughly forms the plane with normal (1, -1, 0) passing through # the origin. # Decrease the number of places of accuracy since these points are # fudged and don't form an exact plane. a = Gf.Vec3d(1.1, 1, 5) b = Gf.Vec3d(1, 1.1, 2) c = Gf.Vec3d(2, 2.1, -4) d = Gf.Vec3d(2.1, 2, 1) e = Gf.Vec3d(25.3, 25.2, 3) f = Gf.Vec3d(25.1, 25.4, 6) p = Gf.FitPlaneToPoints([a, b, c, d, e, f]) expectedNormal = Gf.Vec3d(1, -1, 0).GetNormalized() self.assertAlmostEqual( Gf.Dot(p.GetNormal(), expectedNormal), 1.0, places=2, msg=err("normal3")) self.assertAlmostEqual( p.GetDistanceFromOrigin(), 0.0, places=2, msg=err("distance3"))