Ejemplo n.º 1
0
    def testWorldToRasterPerspective(self):

        v = GafferUI.ViewportGadget()
        v.setViewport(imath.V2i(500, 250))
        v.setCamera(
            IECoreScene.Camera(
                parameters={
                    "resolution":
                    imath.V2i(500, 250),
                    "screenWindow":
                    imath.Box2f(imath.V2f(-1, -.5), imath.V2f(1, .5)),
                    "projection":
                    "perspective",
                    "projection:fov":
                    50.0,
                    "clippingPlanes":
                    imath.V2f(.1, 10),
                }))

        r = imath.Rand48()
        for i in range(0, 100):
            rasterPosition = imath.V2f(r.nexti() % 500, r.nexti() % 250)
            line = v.rasterToWorldSpace(rasterPosition)
            nearProjected = v.worldToRasterSpace(line.p0)
            farProjected = v.worldToRasterSpace(line.p1)
            self.failUnless(
                nearProjected.equalWithAbsError(farProjected, 0.0001))
            self.failUnless(
                imath.V2f(rasterPosition.x,
                          rasterPosition.y).equalWithAbsError(
                              nearProjected, 0.0001))
Ejemplo n.º 2
0
    def rectanglePoints(self,
                        bound=imath.Box2f(imath.V2f(-1), imath.V2f(1)),
                        divisions=imath.V2i(10)):

        r = imath.Rand48()

        pData = IECore.V3fVectorData()
        uData = IECore.FloatVectorData()
        vData = IECore.FloatVectorData()
        floatUserData = IECore.FloatVectorData()
        colorUserData = IECore.Color3fVectorData()
        for y in range(0, divisions.y):
            for x in range(0, divisions.x):
                u = float(x) / float(divisions.x - 1)
                v = float(y) / float(divisions.y - 1)
                pData.append(
                    imath.V3f(bound.min().x + u * bound.size().x,
                              bound.min().y + v * bound.size().y, 0))
                uData.append(u)
                vData.append(v)
                floatUserData.append(r.nextf(0, 1))
                colorUserData.append(
                    imath.Color3f(r.nextf(), r.nextf(), r.nextf()))

        return IECore.CompoundData({
            "P": pData,
            "u": uData,
            "v": vData,
            "floatUserData": floatUserData,
            "colorUserData": colorUserData,
        })
Ejemplo n.º 3
0
    def testWorldToRasterOrthographic(self):

        v = GafferUI.ViewportGadget()
        v.setViewport(imath.V2i(500, 250))
        v.setPlanarMovement(False)
        v.setCamera(
            IECoreScene.Camera(
                parameters={
                    "resolution": imath.V2i(500, 250),
                    "screenWindow": imath.Box2f(imath.V2f(-2, -1),
                                                imath.V2f(2, 1)),
                    "projection": "orthographic",
                    "clippingPlanes": imath.V2f(.1, 10),
                }))

        r = imath.Rand48()
        for i in range(0, 100):
            rasterPosition = imath.V2f(r.nexti() % 500, r.nexti() % 250)
            line = v.rasterToWorldSpace(rasterPosition)
            nearProjected = v.worldToRasterSpace(line.p0)
            farProjected = v.worldToRasterSpace(line.p1)

            self.assertTrue(
                nearProjected.equalWithAbsError(farProjected, 0.0001))
            self.assertTrue(
                imath.V2f(rasterPosition.x,
                          rasterPosition.y).equalWithAbsError(
                              nearProjected, 0.0001))
Ejemplo n.º 4
0
    def testAspectAndRotation(self):

        fragmentSource = """
		void main()
		{
			gl_FragColor = vec4( 1, 1, 1, 1 );
		}
		"""

        random = imath.Rand48()

        p = IECore.V3fVectorData()
        r = IECore.FloatVectorData()
        w = IECore.FloatVectorData()
        a = IECore.FloatVectorData()
        for x in range(-2, 3):
            for y in range(-2, 3):
                p.append(imath.V3f(x, y, 0))
                r.append(random.nextf(0, 360))
                w.append(random.nextf(0.25, 0.5))
                a.append(random.nextf(0.5, 2))

        renderer = IECoreGL.Renderer()
        renderer.setOption("gl:mode", IECore.StringData("immediate"))
        renderer.setOption("gl:searchPath:shaderInclude",
                           IECore.StringData("./glsl"))

        renderer.camera(
            "main", {
                "projection":
                IECore.StringData("orthographic"),
                "resolution":
                IECore.V2iData(imath.V2i(512)),
                "clippingPlanes":
                IECore.V2fData(imath.V2f(1, 1000)),
                "screenWindow":
                IECore.Box2fData(imath.Box2f(imath.V2f(-3), imath.V2f(3)))
            })
        renderer.display(self.outputFileName, "exr", "rgba",
                         {"quantize": IECore.FloatVectorData([0, 0, 0, 0])})

        with IECoreScene.WorldBlock(renderer):

            renderer.concatTransform(imath.M44f().translate(imath.V3f(
                0, 0, -6)))

            renderer.shader(
                "surface", "white",
                {"gl:fragmentSource": IECore.StringData(fragmentSource)})
            renderer.points(
                p.size(), {
                    "P":
                    IECoreScene.PrimitiveVariable(
                        IECoreScene.PrimitiveVariable.Interpolation.Vertex, p),
                    "patchrotation":
                    IECoreScene.PrimitiveVariable(
                        IECoreScene.PrimitiveVariable.Interpolation.Vertex, r),
                    "width":
                    IECoreScene.PrimitiveVariable(
                        IECoreScene.PrimitiveVariable.Interpolation.Vertex, w),
                    "patchaspectratio":
                    IECoreScene.PrimitiveVariable(
                        IECoreScene.PrimitiveVariable.Interpolation.Vertex, a),
                    "type":
                    IECoreScene.PrimitiveVariable(
                        IECoreScene.PrimitiveVariable.Interpolation.Uniform,
                        IECore.StringData("patch")),
                })

        expectedImage = IECore.Reader.create(
            os.path.dirname(__file__) +
            "/expectedOutput/rotatedPointPatches.exr").read()
        actualImage = IECore.Reader.create(self.outputFileName).read()

        self.assertEqual(
            IECoreImage.ImageDiffOp()(imageA=expectedImage,
                                      imageB=actualImage,
                                      maxError=0.08).value, False)
Ejemplo n.º 5
0
    def testSimple(self):
        """ Test SpherePrimitiveEvaluator """

        random.seed(1)

        rand = imath.Rand48(1)

        numTests = 50
        for i in range(0, numTests):

            center = imath.V3f(0, 0, 0)
            radius = random.uniform(0.1, 5)
            sphere = IECoreScene.SpherePrimitive(radius)

            # Add some UV data in "bowtie" order - when we read it back it should then match the geometric UVs
            # if we're doing everything correctly.
            testData = IECore.V3fVectorData()
            testData.append(imath.V3f(0, 0, 0))
            testData.append(imath.V3f(1, 0, 0))
            testData.append(imath.V3f(0, 1, 0))
            testData.append(imath.V3f(1, 1, 0))
            testPrimVar = IECoreScene.PrimitiveVariable(
                IECoreScene.PrimitiveVariable.Interpolation.Varying, testData)
            sphere["testPrimVar"] = testPrimVar

            se = IECoreScene.PrimitiveEvaluator.create(sphere)

            result = se.createResult()

            testPoint = imath.V3f(random.uniform(-10, 10),
                                  random.uniform(-10, 10),
                                  random.uniform(-10, 10))

            found = se.closestPoint(testPoint, result)

            self.assertTrue(found)

            # The closest point should lie on the sphere
            self.assertTrue(
                math.fabs((result.point() - center).length() - radius) < 0.001)

            uv = result.uv()
            self.assertTrue(uv[0] >= 0)
            self.assertTrue(uv[0] <= 1)
            self.assertTrue(uv[1] >= 0)
            self.assertTrue(uv[1] <= 1)

            # Make sure our "fake" UVs match the geometric UVs
            testPrimVarValue = result.vectorPrimVar(testPrimVar)
            self.assertAlmostEqual(testPrimVarValue[0], uv[0], 3)
            self.assertAlmostEqual(testPrimVarValue[1], uv[1], 3)

            closestPoint = result.point()

            found = se.pointAtUV(uv, result)
            self.assertTrue(found)

            self.assertAlmostEqual(result.uv()[0], uv[0], 3)
            self.assertAlmostEqual(result.uv()[1], uv[1], 3)

            # Pick a random point inside the sphere...
            origin = center + rand.nextSolidSphere(imath.V3f()) * radius * 0.9
            self.assertTrue((origin - center).length() < radius)

            # And a random (unnormalized!) direction
            direction = rand.nextHollowSphere(imath.V3f()) * random.uniform(
                0.5, 10)

            found = se.intersectionPoint(origin, direction, result)
            if found:
                # The intersection point should lie on the sphere
                self.assertTrue(
                    math.fabs((result.point() - center).length() -
                              radius) < 0.001)

            results = se.intersectionPoints(origin, direction)

            self.assertTrue(len(results) >= 0)
            self.assertTrue(len(results) <= 1)

            for result in results:
                # The intersection point should lie on the sphere
                self.assertTrue(
                    math.fabs((result.point() - center).length() -
                              radius) < 0.001)

            # Pick a random point outside the sphere...
            origin = center + rand.nextHollowSphere(imath.V3f()) * radius * 2
            self.assertTrue((origin - center).length() > radius)

            found = se.intersectionPoint(origin, direction, result)
            if found:
                # The intersection point should lie on the sphere
                self.assertTrue(
                    math.fabs((result.point() - center).length() -
                              radius) < 0.001)

            results = se.intersectionPoints(origin, direction)

            # We can get a maximum of 2 intersection points from outside the sphere
            self.assertTrue(len(results) >= 0)
            self.assertTrue(len(results) <= 2)

            # If we get 1 result, the ray glances the sphere. Assert this.
            if len(results) == 1:
                self.assertTrue(
                    math.fabs(direction.dot(result.normal()) < 0.1))

            for result in results:
                # The intersection point should lie on the sphere
                self.assertTrue(
                    math.fabs((result.point() - center).length() -
                              radius) < 0.001)
Ejemplo n.º 6
0
    def testRandomTriangles(self):
        """ Testing MeshPrimitiveEvaluator with random triangles"""

        random.seed(100)
        rand = imath.Rand48(100)

        numConfigurations = 100
        numTests = 50
        numTriangles = 250

        for config in range(0, numConfigurations):

            P = IECore.V3fVectorData()
            verticesPerFace = IECore.IntVectorData()
            vertexIds = IECore.IntVectorData()

            vertexId = 0

            for tri in range(0, numTriangles):

                verticesPerFace.append(3)

                P.append(
                    imath.V3f(random.uniform(-10, 10), random.uniform(-10, 10),
                              random.uniform(-10, 10)))
                P.append(
                    imath.V3f(random.uniform(-10, 10), random.uniform(-10, 10),
                              random.uniform(-10, 10)))
                P.append(
                    imath.V3f(random.uniform(-10, 10), random.uniform(-10, 10),
                              random.uniform(-10, 10)))

                vertexIds.append(vertexId + 0)
                vertexIds.append(vertexId + 1)
                vertexIds.append(vertexId + 2)

                vertexId = vertexId + 3

            m = IECoreScene.MeshPrimitive(verticesPerFace, vertexIds)
            m["P"] = IECoreScene.PrimitiveVariable(
                IECoreScene.PrimitiveVariable.Interpolation.Vertex, P)
            mpe = IECoreScene.PrimitiveEvaluator.create(m)
            r = mpe.createResult()
            r2 = mpe.createResult()

            # Make sure that the closest hit point found with intersectionPoint() is actually the closest, by
            # comparing long-hand with the list of all intersections.
            for test in range(0, numTests):

                origin = imath.V3f(0, 0, 0)
                direction = rand.nextHollowSphere(imath.V3f())

                hit = mpe.intersectionPoint(origin, direction, r)

                if hit:

                    hits = mpe.intersectionPoints(origin, direction)
                    self.assertTrue(hits)

                    closestHitDist = 100000

                    closestHit = None

                    for hit in hits:

                        hitDist = (origin - hit.point()).length()
                        if hitDist < closestHitDist:

                            closestHitDist = hitDist
                            closestHit = hit

                    self.assertTrue(
                        (r.point() - closestHit.point()).length() < 1.e-4)

                    barycentricQuerySucceeded = mpe.barycentricPosition(
                        r.triangleIndex(), r.barycentricCoordinates(), r2)
                    self.assertTrue(barycentricQuerySucceeded)
                    self.assertTrue(r.point().equalWithAbsError(
                        r2.point(), 0.00001))
                    self.assertTrue(r.normal().equalWithAbsError(
                        r2.normal(), 0.00001))
                    self.assertTrue(
                        r.barycentricCoordinates().equalWithAbsError(
                            r2.barycentricCoordinates(), 0.00001))
                    self.assertEqual(r.triangleIndex(), r2.triangleIndex())

                else:

                    hits = mpe.intersectionPoints(origin, direction)
                    self.assertFalse(hits)
Ejemplo n.º 7
0
    def testSphereMesh(self):
        """ Testing MeshPrimitiveEvaluator with sphere mesh"""

        # File represents a sphere of radius 1.0 at the origin
        reader = IECore.Reader.create(
            "test/IECore/data/cobFiles/pSphereShape1.cob")
        m = reader.read()

        self.assertTrue(m.isInstanceOf("MeshPrimitive"))

        numTriangles = len(m.verticesPerFace)

        mpe = IECoreScene.PrimitiveEvaluator.create(m)

        maxAbsError = 0.2

        # Test volume against (theoretical) 4/3 * pi * r^3
        self.assertTrue(
            math.fabs(4.0 / 3.0 * math.pi *
                      (1.0 * 1.0 * 1.0) - mpe.volume()) < maxAbsError)

        # Center of gravity should be at origin
        self.assertTrue(mpe.centerOfGravity().length() < maxAbsError)

        # Test surface area against (theoretical) 4 * pi * r^20
        self.assertTrue(
            math.fabs(4.0 * math.pi *
                      (1.0 * 1.0) - mpe.surfaceArea()) < maxAbsError)

        r = mpe.createResult()

        random.seed(1)

        # Perform 100 closest point queries
        for i in range(0, 100):

            # Pick a random point outside the sphere
            testPt = None
            while not testPt or testPt.length() < 1.5:
                testPt = 3 * imath.V3f(random.uniform(
                    -1, 1), random.uniform(-1, 1), random.uniform(-1, 1))

            foundClosest = mpe.closestPoint(testPt, r)

            self.assertTrue(foundClosest)

            # Closest point should lie on unit sphere
            self.assertTrue(math.fabs(r.point().length() - 1.0) < maxAbsError)

            # Distance to closest point should be approximately distance to origin minus sphere radius - allow some error
            # because our source mesh does not represent a perfect sphere.
            absError = math.fabs((testPt - r.point()).length() -
                                 (testPt.length() - 1.0))

            self.assertTrue(absError < maxAbsError)

            self.assertTrue(r.triangleIndex() >= 0)
            self.assertTrue(r.triangleIndex() < numTriangles)

            # Origin->Closest point should be roughly same direction as Origin->Test point, for a sphere
            self.assertTrue(
                r.point().normalized().dot(testPt.normalized()) > 0.5)

            geometricNormal = r.normal().normalized()
            shadingNormal = r.vectorPrimVar(m["N"]).normalized()

            # Geometric and shading normals should be facing the same way, roughly
            self.assertTrue(geometricNormal.dot(shadingNormal) > 0.5)

            # Shading normal should be pointing away from the origin at the closest point
            self.assertTrue(shadingNormal.dot(r.point().normalized()) > 0.5)

            # Vector from closest point to test point should be roughly the same direction as the normal
            self.assertTrue(
                shadingNormal.dot((testPt - r.point()).normalized()) > 0.5)

        rand = imath.Rand48()

        # Perform 100 ray intersection queries from inside the sphere, in random directions
        for i in range(0, 100):

            origin = rand.nextSolidSphere(imath.V3f()) * 0.5
            direction = rand.nextHollowSphere(imath.V3f())
            hit = mpe.intersectionPoint(origin, direction, r)
            self.assertTrue(hit)
            self.assertTrue(math.fabs(r.point().length() - 1) < 0.1)

            hits = mpe.intersectionPoints(origin, direction)
            self.assertEqual(len(hits), 1)

            for hit in hits:
                self.assertTrue(math.fabs(hit.point().length() - 1) < 0.1)

        # Perform 100 nearest ray intersection queries from outside the sphere, going outwards
        for i in range(0, 100):

            direction = rand.nextHollowSphere(imath.V3f())
            origin = direction * 2

            hit = mpe.intersectionPoint(origin, direction, r)
            self.assertFalse(hit)

            hits = mpe.intersectionPoints(origin, direction)
            self.assertFalse(hits)

        # Perform 100 nearest ray intersection queries from outside the sphere, going inwards
        for i in range(0, 100):

            direction = -rand.nextHollowSphere(imath.V3f())
            origin = -direction * 2

            hit = mpe.intersectionPoint(origin, direction, r)
            self.assertTrue(hit)
            self.assertTrue(math.fabs(r.point().length() - 1) < 0.1)

            # Make sure we get the nearest point, not the furthest
            self.assertTrue((origin - r.point()).length() < 1.1)

            hits = mpe.intersectionPoints(origin, direction)

            # There should be 0, 1, or 2 intersections
            self.assertTrue(len(hits) >= 0)
            self.assertTrue(len(hits) <= 2)

            for hit in hits:
                self.assertTrue(math.fabs(hit.point().length() - 1) < 0.1)