//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(PrimitiveSetIndexedUInt, GetOpenGLPrimitive_FromTriangles)
{
    ref<UIntArray> indices = new UIntArray;
    indices->reserve(6);
    indices->add(0);  
    indices->add(1);  
    indices->add(2);
    indices->add(3);
    indices->add(4);
    indices->add(5);

    ref<PrimitiveSetIndexedUInt> myPrim = new PrimitiveSetIndexedUInt(PT_TRIANGLES);
    myPrim->setIndices(indices.p());

    ASSERT_EQ(2u, myPrim->faceCount());

    UIntArray conn;
    
    myPrim->getFaceIndices(0, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(0u, conn.get(0));
    EXPECT_EQ(1u, conn.get(1));
    EXPECT_EQ(2u, conn.get(2));

    myPrim->getFaceIndices(1, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(3u, conn.get(0));
    EXPECT_EQ(4u, conn.get(1));
    EXPECT_EQ(5u, conn.get(2));
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(PrimitiveSetIndexedUInt, GetOpenGLPrimitive_FromLineStrip)
{
    ref<UIntArray> indices = new UIntArray;
    indices->reserve(4);
    indices->add(0);  
    indices->add(1);  
    indices->add(2);
    indices->add(3);

    ref<PrimitiveSetIndexedUInt> myPrim = new PrimitiveSetIndexedUInt(PT_LINE_STRIP);
    myPrim->setIndices(indices.p());

    ASSERT_EQ(3u, myPrim->faceCount());

    UIntArray conn;

    myPrim->getFaceIndices(0, &conn);
    ASSERT_EQ(2u, conn.size());
    EXPECT_EQ(0u, conn.get(0));
    EXPECT_EQ(1u, conn.get(1));

    myPrim->getFaceIndices(1, &conn);
    ASSERT_EQ(2u, conn.size());
    EXPECT_EQ(1u, conn.get(0));
    EXPECT_EQ(2u, conn.get(1));

    myPrim->getFaceIndices(2, &conn);
    ASSERT_EQ(2u, conn.size());
    EXPECT_EQ(2u, conn.get(0));
    EXPECT_EQ(3u, conn.get(1));
}
예제 #3
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool DrawableGeo::rayIntersect(const Ray& ray, Vec3dArray* intersectionPoints, UIntArray* facesHit) const
{
    if (intersectionPoints) intersectionPoints->setSizeZero();
    if (facesHit) facesHit->setSizeZero();

    std::vector<Vec3d> isectPts;
    std::vector<uint> faceIndices;

    cref<Vec3fArray> vertexArr = m_vertexBundle->vertexArray();
    int accumulatedFaceCount = 0;

    size_t numPrimitiveSets = m_primitiveSets.size();
    size_t iPrimSet;
    for (iPrimSet = 0; iPrimSet < numPrimitiveSets; iPrimSet++)
    {
        const PrimitiveSet* primSet = m_primitiveSets.at(iPrimSet);
        CVF_TIGHT_ASSERT(primSet);

        UIntArray conn;
        int numPrimFaces = static_cast<int>(primSet->faceCount());
#pragma omp parallel for private(conn)
        for (int i = 0; i < numPrimFaces; i++)
        {
            bool hitThisFace = false;
            Vec3d localIntersect;

            primSet->getFaceIndices(static_cast<size_t>(i), &conn);
            int numconn = static_cast<int>(conn.size());
            if (numconn == 3)
            {
                hitThisFace = ray.triangleIntersect(Vec3d(vertexArr->get(conn[0])), 
                                                    Vec3d(vertexArr->get(conn[1])), 
                                                    Vec3d(vertexArr->get(conn[2])), 
                                                    &localIntersect);
            }

            if (hitThisFace)
            {
              #pragma omp critical
	      {
                isectPts.push_back(localIntersect);
                faceIndices.push_back(i + accumulatedFaceCount);
	      }
            }
        }
        accumulatedFaceCount += numPrimFaces;
    }

    if (isectPts.size() > 0)
    {
        if (intersectionPoints) intersectionPoints->assign(isectPts);
        if (facesHit) facesHit->assign(faceIndices);

        return true;
    }
    else
    {
        return false;
    }
}
예제 #4
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(ArrayTest, setConsecutiveEmpty)
{
    UIntArray arr;
    arr.setConsecutive(0);

    EXPECT_EQ(0, arr.size());
}
Beagle::MPI::GA::EvolverBitString::EvolverBitString(UIntArray inInitSize)

{
    if(inInitSize.size()==0) addOperator(new Beagle::GA::InitBitStrOp(0));
    else if(inInitSize.size()==1) addOperator(new Beagle::GA::InitBitStrOp(inInitSize[0]));
    else {
        std::ostringstream lOSS;
        lOSS << "Initialization of bit string individuals with more than one bit string ";
        lOSS << "is no more valid. You should use individuals made of one bit string, or ";
        lOSS << "define your own bit string initialization operator.";
        throw Beagle_RunTimeExceptionM(lOSS.str());
    }
    addOperator(new Beagle::GA::CrossoverOnePointBitStrOp);
    addOperator(new Beagle::GA::CrossoverTwoPointsBitStrOp);
    addOperator(new Beagle::GA::CrossoverUniformBitStrOp);
    addOperator(new Beagle::GA::MutationFlipBitStrOp);
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(MeshEdgeExtractorTest, PrimitiveMixFromFaceList)
{
    //           6----5
    //          /      \      *11
    //         /        \         *12
    // 8------7          4-----9   
    // |      |\        /      |
    // |      | \      /       |
    // 0------1--2----3       10   

    UIntArray fl;
    fl.reserve(26);

    fl.add(1);  fl.add(11);  
    fl.add(1);  fl.add(12);
    fl.add(2);  fl.add(4);  fl.add(9);  
    fl.add(2);  fl.add(10); fl.add(9);  
    fl.add(3);  fl.add(1);  fl.add(2);  fl.add(7); 
    fl.add(4);  fl.add(0);  fl.add(1);  fl.add(7);  fl.add(8); 
    fl.add(6);  fl.add(2);  fl.add(3);  fl.add(4);  fl.add(5);  fl.add(6);  fl.add(7); 
    ASSERT_EQ(26, fl.size());


    MeshEdgeExtractor ee;
    ee.addFaceList(fl);

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*13, li.size());

    EXPECT_EQ(0, li[ 0]);    EXPECT_EQ(1, li[ 1]);
    EXPECT_EQ(0, li[ 2]);    EXPECT_EQ(8, li[ 3]);
    EXPECT_EQ(1, li[ 4]);    EXPECT_EQ(2, li[ 5]);
    EXPECT_EQ(1, li[ 6]);    EXPECT_EQ(7, li[ 7]);
    EXPECT_EQ(2, li[ 8]);    EXPECT_EQ(3, li[ 9]);
    EXPECT_EQ(2, li[10]);    EXPECT_EQ(7, li[11]);
    EXPECT_EQ(3, li[12]);    EXPECT_EQ(4, li[13]);
    EXPECT_EQ(4, li[14]);    EXPECT_EQ(5, li[15]);
    EXPECT_EQ(4, li[16]);    EXPECT_EQ(9, li[17]);
    EXPECT_EQ(5, li[18]);    EXPECT_EQ(6, li[19]);
    EXPECT_EQ(6, li[20]);    EXPECT_EQ(7, li[21]);
    EXPECT_EQ(7, li[22]);    EXPECT_EQ(8, li[23]);
    EXPECT_EQ(9, li[24]);    EXPECT_EQ(10,li[25]);
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(PrimitiveSetIndexedUInt, GetOpenGLPrimitive_FromTriStrip)
{
    // See TEST(GeometryBuilderTest, AddTriangleStrip)
    ref<UIntArray> indices = new UIntArray;
    indices->reserve(6);
    indices->add(0);  
    indices->add(1);  
    indices->add(2);
    indices->add(3);
    indices->add(4);
    indices->add(5);

    ref<PrimitiveSetIndexedUInt> myPrim = new PrimitiveSetIndexedUInt(PT_TRIANGLE_STRIP);
    myPrim->setIndices(indices.p());

    ASSERT_EQ(4u, myPrim->faceCount());

    UIntArray conn;
    
    myPrim->getFaceIndices(0, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(0u, conn.get(0));
    EXPECT_EQ(1u, conn.get(1));
    EXPECT_EQ(2u, conn.get(2));

    myPrim->getFaceIndices(1, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(2u, conn.get(0));
    EXPECT_EQ(1u, conn.get(1));
    EXPECT_EQ(3u, conn.get(2));

    myPrim->getFaceIndices(2, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(2u, conn.get(0));
    EXPECT_EQ(3u, conn.get(1));
    EXPECT_EQ(4u, conn.get(2));

    myPrim->getFaceIndices(3, &conn);
    ASSERT_EQ(3u, conn.size());
    EXPECT_EQ(4u, conn.get(0));
    EXPECT_EQ(3u, conn.get(1));
    EXPECT_EQ(5u, conn.get(2));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OutlineEdgeExtractor::addPrimitives(uint verticesPerPrimitive, const UIntArray& indices)
{
    CVF_ASSERT(verticesPerPrimitive > 0);

    size_t indexCount = indices.size();
    size_t numPrimitives = indexCount/verticesPerPrimitive;
    if (numPrimitives > 0)
    {
        const uint* indexPtr = indices.ptr();
        addPrimitives(verticesPerPrimitive, indexPtr, indexCount);
    }
}
예제 #9
0
//--------------------------------------------------------------------------------------------------
/// Add a triangle fan
/// 
/// Vertex ordering for triangle fans:
/// <PRE>
///   v4 *-------* v3        Resulting triangles:
///       \     / \            t1: v0, v1, v2
///        \   /   \           t2: v0, v2, v3
///         \ /     \          t3: v0, v3, v4
///       v0 *-------* v2        
///           \     /
///            \   /
///             \ /
///              * v1 </PRE>
/// 
/// \remarks The number of entries in the \a indices array must be at least 3.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangleFan(const UIntArray& indices)
{
    size_t numIndices = indices.size();
    CVF_ASSERT(numIndices >= 3);

    size_t numTriangles = numIndices - 2;
    CVF_ASSERT(numTriangles >= 1);

    size_t i;
    for (i = 0; i < numTriangles; i++)
    {
        addTriangle(indices[0], indices[i + 1], indices[i + 2]);
    }
}
/*!
 *  \brief Construct a GA Generational evolver.
 *  \param inEvalOp Evaluation operator.
 *  \param inInitSize Size of the GA bit strings.
 *  \deprecated Use EvolverBitString(EvaluationOp::Handle,unsigned int) constructor instead.
 *  \throw Beagle::RunTimeException If init size vector has more than one value.
 */
Beagle::MPI::GA::EvolverBitString::EvolverBitString(EvaluationOp::Handle inEvalOp, UIntArray inInitSize) : Beagle::MPI::Evolver(inEvalOp)
{
    addOperator(inEvalOp);
    if(inInitSize.size()==0) addOperator(new Beagle::GA::InitBitStrOp(0));
    else if(inInitSize.size()==1) addOperator(new Beagle::GA::InitBitStrOp(inInitSize[0]));
    else {
        std::ostringstream lOSS;
        lOSS << "Initialization of bit string individuals with more than one bit string ";
        lOSS << "is no more valid. You should use individuals made of one bit string, or ";
        lOSS << "define your own bit string initialization operator.";
        throw Beagle_RunTimeExceptionM(lOSS.str());
    }
    addOperator(new Beagle::GA::CrossoverOnePointBitStrOp);
    addOperator(new Beagle::GA::CrossoverTwoPointsBitStrOp);
    addOperator(new Beagle::GA::CrossoverUniformBitStrOp);
    addOperator(new Beagle::GA::MutationFlipBitStrOp);

    addBootStrapOp("IfThenElseOp");
    IfThenElseOp::Handle lITE = castHandleT<IfThenElseOp>(getBootStrapSet().back());
    lITE->setConditionTag("ms.restart.file");
    lITE->setConditionValue("");
    lITE->insertPositiveOp("GA-InitBitStrOp", getOperatorMap());
    lITE->insertPositiveOp(inEvalOp->getName(), getOperatorMap());
    lITE->insertPositiveOp("StatsCalcFitnessSimpleOp", getOperatorMap());
    lITE->insertNegativeOp("MilestoneReadOp", getOperatorMap());
    addBootStrapOp("TermMaxGenOp");
    addBootStrapOp("MilestoneWriteOp");

    addMainLoopOp("SelectTournamentOp");
    addMainLoopOp("GA-CrossoverOnePointBitStrOp");
    addMainLoopOp("GA-MutationFlipBitStrOp");
    addMainLoopOp(inEvalOp->getName());
    addMainLoopOp("MigrationRandomRingOp");
    addMainLoopOp("StatsCalcFitnessSimpleOp");
    addMainLoopOp("TermMaxGenOp");
    addMainLoopOp("MilestoneWriteOp");
}
예제 #11
0
//--------------------------------------------------------------------------------------------------
/// Add a quad strip
/// 
/// Vertex ordering for quad strips:
/// <PRE>
///   v0    v2    v4    v6   Resulting quads:
///   *-----*-----*-----*       q1: v0, v1, v3, v2
///   |     |     |     |       q2: v2, v3, v5, v4
///   |     |     |     |       q3: v4, v5, v7, v6
///   |     |     |     |       
///   *-----*-----*-----*
///   v1    v3    v5    v7 </PRE>
/// 
/// \remarks There must be at least 4 entries in the \a indices array, and the total number of 
///          entries must be a multiple of 2.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuadStrip(const UIntArray& indices)
{
    size_t numIndices = indices.size();
    CVF_ASSERT(numIndices >= 4);
    CVF_ASSERT(numIndices % 2 == 0);

    size_t numQuads = (numIndices - 2)/2;
    CVF_ASSERT(numQuads >= 1);

    size_t i;
    for (i = 0; i < numQuads; i++)
    {
        addQuad(indices[2*i], indices[2*i + 1], indices[2*i + 3], indices[2*i + 2]);
    }
}
예제 #12
0
//--------------------------------------------------------------------------------------------------
/// Add multiple triangles
/// 
/// \remarks There must be at least 3 entries in the \a indices array, and the total number of 
///          entries must be a multiple of 3.   
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangles(const UIntArray& indices)
{
    size_t numIndices = indices.size();
    CVF_ASSERT(numIndices >= 3);
    CVF_ASSERT(numIndices % 3 == 0);

    size_t numTriangles = numIndices/3;
    CVF_ASSERT(numTriangles >= 1);
    CVF_ASSERT(3*numTriangles == numIndices);

    size_t i;
    for (i = 0; i < numTriangles; i++)
    {
        addTriangle(indices[3*i], indices[3*i + 1], indices[3*i + 2]);
    }
}
예제 #13
0
//--------------------------------------------------------------------------------------------------
/// Add multiple quads
/// 
/// The default implementation utilizes addQuad() to add each quad separately.
/// 
/// \remarks There must be at least 4 entries in the \a indices array, and the total number of 
///          entries must be a multiple of 4.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuads(const UIntArray& indices)
{
    size_t numIndices = indices.size();
    CVF_ASSERT(numIndices >= 4);
    CVF_ASSERT(numIndices % 4 == 0);

    size_t numQuads = numIndices/4;
    CVF_ASSERT(numQuads >= 1);
    CVF_ASSERT(4*numQuads == numIndices);

    size_t i;
    for (i = 0; i < numQuads; i++)
    {
        addQuad(indices[4*i], indices[4*i + 1], indices[4*i + 2], indices[4*i + 3]);
    }
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OutlineEdgeExtractor::addFaceList(const UIntArray& faceList)
{
    size_t numFaceListEntries = faceList.size();

    size_t i = 0;
    while (i < numFaceListEntries)
    {
        uint numVerticesInFace = faceList[i++];
        CVF_ASSERT(numVerticesInFace > 0);
        CVF_ASSERT(i + numVerticesInFace <= numFaceListEntries);

        const uint* indexPtr = &faceList[i];
        addPrimitives(numVerticesInFace, indexPtr, numVerticesInFace);

        i += numVerticesInFace;
    }
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(OutlineEdgeExtractorTest, ThreeQuads)
{
    ref<Vec3fArray> va = new Vec3fArray;
    va->reserve(8);
    va->add(Vec3f(0, 0, 0));
    va->add(Vec3f(1, 0, 0));
    va->add(Vec3f(2, 0, 0));
    va->add(Vec3f(3, 0, 0));
    va->add(Vec3f(0, 1, 0));
    va->add(Vec3f(1, 1, 0));
    va->add(Vec3f(2, 1, 0));
    va->add(Vec3f(3, 1, 0));

    // 4------5------6------7
    // |      |      |      | 
    // |      |      |      | 
    // 0------1------2------3

    OutlineEdgeExtractor ee(0, *va);

    {
        const cvf::uint conn[8] = { 0, 1, 5, 4,  1, 2, 6, 5 };
        ee.addPrimitives(4, conn, 8);
    }

    {
        const cvf::uint conn[4] = { 2, 3, 7, 6 };
        ee.addPrimitives(4, conn, 4);
    }

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*8, li.size());

    EXPECT_TRUE( EdgeKey(0, 1) == EdgeKey(li[ 0], li[ 1]) );
    EXPECT_TRUE( EdgeKey(0, 4) == EdgeKey(li[ 2], li[ 3]) );
    EXPECT_TRUE( EdgeKey(1, 2) == EdgeKey(li[ 4], li[ 5]) );
    EXPECT_TRUE( EdgeKey(2, 3) == EdgeKey(li[ 6], li[ 7]) );
    EXPECT_TRUE( EdgeKey(3, 7) == EdgeKey(li[ 8], li[ 9]) );
    EXPECT_TRUE( EdgeKey(4, 5) == EdgeKey(li[10], li[11]) );
    EXPECT_TRUE( EdgeKey(5, 6) == EdgeKey(li[12], li[13]) );
    EXPECT_TRUE( EdgeKey(6, 7) == EdgeKey(li[14], li[15]) );
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(MeshEdgeExtractorTest, PrimitiveMixFromRawArrays)
{
    //           6----5
    //          /      \      *11
    //         /        \         *12
    // 8------7          4-----9   
    // |      |\        /      |
    // |      | \      /       |
    // 0------1--2----3       10   

    const cvf::uint points[2] = { 11, 12 };
    const cvf::uint lines[4]  = { 4, 9, 10, 9 };
    const cvf::uint tri[3]    = { 1, 2, 7 };
    const cvf::uint quad[4]   = { 0, 1, 7, 8 };
    const cvf::uint poly[6]   = { 2, 3, 4, 5, 6, 7 };

    MeshEdgeExtractor ee;
    ee.addPrimitives(1, points, 2);
    ee.addPrimitives(2, lines, 4);
    ee.addPrimitives(3, tri, 3);
    ee.addPrimitives(4, quad, 4);
    ee.addPrimitives(6, poly, 6);

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*13, li.size());

    EXPECT_EQ(0, li[ 0]);    EXPECT_EQ(1, li[ 1]);
    EXPECT_EQ(0, li[ 2]);    EXPECT_EQ(8, li[ 3]);
    EXPECT_EQ(1, li[ 4]);    EXPECT_EQ(2, li[ 5]);
    EXPECT_EQ(1, li[ 6]);    EXPECT_EQ(7, li[ 7]);
    EXPECT_EQ(2, li[ 8]);    EXPECT_EQ(3, li[ 9]);
    EXPECT_EQ(2, li[10]);    EXPECT_EQ(7, li[11]);
    EXPECT_EQ(3, li[12]);    EXPECT_EQ(4, li[13]);
    EXPECT_EQ(4, li[14]);    EXPECT_EQ(5, li[15]);
    EXPECT_EQ(4, li[16]);    EXPECT_EQ(9, li[17]);
    EXPECT_EQ(5, li[18]);    EXPECT_EQ(6, li[19]);
    EXPECT_EQ(6, li[20]);    EXPECT_EQ(7, li[21]);
    EXPECT_EQ(7, li[22]);    EXPECT_EQ(8, li[23]);
    EXPECT_EQ(9, li[24]);    EXPECT_EQ(10,li[25]);
}
예제 #17
0
//--------------------------------------------------------------------------------------------------
/// Add one face 
/// 
/// The type of primitive added will be determined from the number of indices passed in \a indices
/// 
/// \remarks Currently, points and lines are not supported. Faces with more than 4 indices will
///          be triangulated using fanning
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addFace(const UIntArray& indices)
{
    size_t numIndices = indices.size();
    CVF_ASSERT(numIndices >= 3);

    if (numIndices == 3)
    {
        addTriangle(indices[0], indices[1], indices[2]);
    }
    else if (numIndices == 4)
    {
        addQuad(indices[0], indices[1], indices[2], indices[3]);
    }
    else
    {
        size_t numTriangles = numIndices - 2;
        size_t i;
        for (i = 0; i < numTriangles; i++)
        {
            addTriangle(indices[0], indices[i + 1], indices[i + 2]);
        }
    }
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(MeshEdgeExtractorTest, CollapsedQuads)
{
    // 4------3        6,6
    // |      |\        |
    // |      | \       |
    // 0------1--2,2   5,5

    const cvf::uint quads[12] = { 0, 1, 3, 4,   1, 2, 2, 3,   6, 5, 5, 6 };

    MeshEdgeExtractor ee;
    ee.addPrimitives(4, quads, 12);

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*7, li.size());

    EXPECT_EQ(0, li[ 0]);    EXPECT_EQ(1, li[ 1]);
    EXPECT_EQ(0, li[ 2]);    EXPECT_EQ(4, li[ 3]);
    EXPECT_EQ(1, li[ 4]);    EXPECT_EQ(2, li[ 5]);
    EXPECT_EQ(1, li[ 6]);    EXPECT_EQ(3, li[ 7]);
    EXPECT_EQ(2, li[ 8]);    EXPECT_EQ(3, li[ 9]);
    EXPECT_EQ(3, li[10]);    EXPECT_EQ(4, li[11]);
    EXPECT_EQ(5, li[12]);    EXPECT_EQ(6, li[13]);
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(OutlineEdgeExtractorTest, CollapsedPrimitives)
{
    ref<Vec3fArray> va = new Vec3fArray;
    va->reserve(4);
    va->add(Vec3f(0, 0, 0));
    va->add(Vec3f(1, 0, 0));
    va->add(Vec3f(1, 1, 0));

    // Collapsed tris
    {
        const cvf::uint conn[3] = { 0, 1, 0 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(3, conn, 3);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(2, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
    }

    {
        const cvf::uint conn[3] = { 0, 0, 1 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(3, conn, 3);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(2, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
    }

    {
        const cvf::uint conn[3] = { 1, 1, 1 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(3, conn, 3);

        UIntArray li = *ee.lineIndices();
        EXPECT_EQ(0, li.size());
    }


    // Collapsed quads
    {
        const cvf::uint conn[4] = { 0, 1, 1, 2};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(6, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
        EXPECT_EQ(0, li[2]); 
        EXPECT_EQ(2, li[3]);
        EXPECT_EQ(1, li[4]); 
        EXPECT_EQ(2, li[5]);
    }

    {
        const cvf::uint conn[4] = { 0, 1, 2, 0};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(6, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
        EXPECT_EQ(0, li[2]); 
        EXPECT_EQ(2, li[3]);
        EXPECT_EQ(1, li[4]); 
        EXPECT_EQ(2, li[5]);
    }

    {
        const cvf::uint conn[4] = { 0, 1, 0, 1};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(2, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
    }

    {
        const cvf::uint conn[4] = { 1, 1, 0, 1};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(2, li.size());
        EXPECT_EQ(0, li[0]); 
        EXPECT_EQ(1, li[1]);
    }

    {
        const cvf::uint conn[4] = { 2, 2, 2, 2};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        EXPECT_EQ(0, li.size());
    }
}
예제 #20
0
//--------------------------------------------------------------------------------------------------
/// Sets the DrawableGeo object's geometry representation from a face list
/// 
/// \param faceList Face list
///
/// faceList contains number of items before each face connectivities. E.g. 3 0 1 2   3 2 3 1   3 2 1 3
///
/// \note This method will use more temporary memory than strictly needed in order to optimize 
///       performance.
//--------------------------------------------------------------------------------------------------
void DrawableGeo::setFromFaceList(const UIntArray& faceList)
{
    m_primitiveSets.clear();

    size_t numFaceListEntries = faceList.size();

    ref<UIntArray> triangleConnects = new UIntArray;
	triangleConnects->reserve(numFaceListEntries*3);		// Usually too much, but temporary and will be squeezed if kept.

    size_t i = 0;
    while (i < numFaceListEntries)
    {
        uint numConnects = faceList[i++];
        CVF_ASSERT(numConnects >= 3);

        if (numConnects == 3)
        {
			triangleConnects->add(faceList[i++]);
			triangleConnects->add(faceList[i++]);
			triangleConnects->add(faceList[i++]);
		}
		else 
		{
            size_t j;
            for (j = 0; j < numConnects - 2;  j++)
            {
                triangleConnects->add(faceList[i]);
                triangleConnects->add(faceList[i + 1 + j]);
                triangleConnects->add(faceList[i + 2 + j]);
            }

            i += numConnects;
		}
    }

    // Check if the largest index used in the triangle connects exceeds short representation
	if (triangleConnects->max() < std::numeric_limits<ushort>::max())
	{
		// Create an USHORT primitive set
		size_t arraySize = triangleConnects->size();

		ref<UShortArray> shortIndices = new UShortArray;
		shortIndices->resize(arraySize);

		size_t j;
		for (j = 0; j < arraySize; j++)
		{
			shortIndices->set(j, static_cast<ushort>(triangleConnects->get(j)));
		}

		ref<PrimitiveSetIndexedUShort> prim = new PrimitiveSetIndexedUShort(PT_TRIANGLES);
		prim->setIndices(shortIndices.p());

		m_primitiveSets.push_back(prim.p());
	}
	else
	{
		// Create a UINT primitive set
		ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(PT_TRIANGLES);

		triangleConnects->squeeze();
		prim->setIndices(triangleConnects.p());
		m_primitiveSets.push_back(prim.p());
	}
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(OutlineEdgeExtractorTest, PrimitiveMixFromFaceList)
{
    ref<Vec3fArray> va = new Vec3fArray;
    va->resize(13);
    va->set( 0, Vec3f(0, 0, 0));
    va->set( 1, Vec3f(1, 0, 0));
    va->set( 2, Vec3f(2, 0, 0));
    va->set( 3, Vec3f(3, 0, 0));
    va->set( 4, Vec3f(4, 1, 0));
    va->set( 5, Vec3f(3, 2, 0));
    va->set( 6, Vec3f(2, 2, 0));
    va->set( 7, Vec3f(1, 1, 0));
    va->set( 8, Vec3f(0, 1, 0));
    va->set( 9, Vec3f(5, 1, 0));
    va->set(10, Vec3f(5, 0, 0));
    va->set(11, Vec3f(6, 6, 0));
    va->set(12, Vec3f(7, 7, 0));

    //                 
    //                        *11
    //                            *12
    // 8------7          4-----9   
    // |      |\               |
    // |      | \              |
    // 0------1--2            10   

    UIntArray fl;
    fl.reserve(26);

    fl.add(1);  fl.add(11);  
    fl.add(1);  fl.add(12);
    fl.add(2);  fl.add(4);  fl.add(9);  
    fl.add(2);  fl.add(10); fl.add(9);  
    fl.add(3);  fl.add(1);  fl.add(2);  fl.add(7); 
    fl.add(4);  fl.add(0);  fl.add(1);  fl.add(7);  fl.add(8); 
    ASSERT_EQ(19, fl.size());

    OutlineEdgeExtractor ee(0, *va);
    ee.addFaceList(fl);

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*7, li.size());

    EXPECT_TRUE( EdgeKey(0, 1) == EdgeKey(li[ 0], li[ 1]) );
    EXPECT_TRUE( EdgeKey(0, 8) == EdgeKey(li[ 2], li[ 3]) );
    EXPECT_TRUE( EdgeKey(1, 2) == EdgeKey(li[ 4], li[ 5]) );
    EXPECT_TRUE( EdgeKey(2, 7) == EdgeKey(li[ 6], li[ 7]) );
    EXPECT_TRUE( EdgeKey(4, 9) == EdgeKey(li[ 8], li[ 9]) );
    EXPECT_TRUE( EdgeKey(7, 8) == EdgeKey(li[10], li[11]) );
    EXPECT_TRUE( EdgeKey(9,10) == EdgeKey(li[12], li[13]) );

    /*
    //           6----5
    //          /      \      *11
    //         /        \         *12
    // 8------7          4-----9   
    // |      |\        /      |
    // |      | \      /       |
    // 0------1--2----3       10   

    fl.add(1);  fl.add(11);  
    fl.add(1);  fl.add(12);
    fl.add(2);  fl.add(4);  fl.add(9);  
    fl.add(2);  fl.add(10); fl.add(9);  
    fl.add(3);  fl.add(1);  fl.add(2);  fl.add(7); 
    fl.add(4);  fl.add(0);  fl.add(1);  fl.add(7);  fl.add(8); 
    fl.add(6);  fl.add(2);  fl.add(3);  fl.add(4);  fl.add(5);  fl.add(6);  fl.add(7); 
    ASSERT_EQ(26, fl.size());

    OutlineEdgeExtractor ee(0, *va);
    ee.addFaceList(fl);

    UIntArray li = *ee.lineIndices();
    ASSERT_EQ(2*11, li.size());

    EXPECT_TRUE( EdgeKey(0, 1) == EdgeKey(li[ 0], li[ 1]) );
    EXPECT_TRUE( EdgeKey(0, 8) == EdgeKey(li[ 2], li[ 3]) );
    EXPECT_TRUE( EdgeKey(1, 2) == EdgeKey(li[ 4], li[ 5]) );
    EXPECT_TRUE( EdgeKey(2, 3) == EdgeKey(li[ 6], li[ 7]) );
    EXPECT_TRUE( EdgeKey(3, 4) == EdgeKey(li[ 8], li[ 9]) );
    EXPECT_TRUE( EdgeKey(4, 5) == EdgeKey(li[10], li[11]) );
    EXPECT_TRUE( EdgeKey(4, 9) == EdgeKey(li[12], li[13]) );
    EXPECT_TRUE( EdgeKey(5, 6) == EdgeKey(li[14], li[15]) );
    EXPECT_TRUE( EdgeKey(6, 7) == EdgeKey(li[16], li[17]) );
    EXPECT_TRUE( EdgeKey(7, 8) == EdgeKey(li[18], li[19]) );
    EXPECT_TRUE( EdgeKey(9,10) == EdgeKey(li[20], li[21]) );
    */
}
예제 #22
0
//--------------------------------------------------------------------------------------------------
/// Intersect the drawable geo with the ray and return the closest intersection point and the face hit
///
/// Returns true if anything was hit.
//--------------------------------------------------------------------------------------------------
bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* faceHit) const
{
    CVF_ASSERT(intersectionPoint);

    bool anyHits = false;
    double minDistSquared = 1.0e300;

    cref<Vec3fArray> vertexArr = m_vertexBundle->vertexArray();

    size_t numPrimitiveSets = m_primitiveSets.size();
    size_t iPrimSet;
    int accumulatedFaceCount = 0;

    for (iPrimSet = 0; iPrimSet < numPrimitiveSets; iPrimSet++)
    {
        const PrimitiveSet* primSet = m_primitiveSets.at(iPrimSet);
        CVF_TIGHT_ASSERT(primSet);

        UIntArray conn;
        int numPrimFaces = static_cast<int>(primSet->faceCount());

#pragma omp parallel for private (conn)
        for (int i = 0; i < numPrimFaces; i++)
        {
            bool hitThisFace = false;
            Vec3d localIntersect;

            primSet->getFaceIndices(static_cast<size_t>(i), &conn);
            int numconn = static_cast<int>(conn.size());
            CVF_TIGHT_ASSERT(numconn <= 3);
            if (numconn == 3)
            {
                hitThisFace = ray.triangleIntersect(Vec3d(vertexArr->get(conn[0])), 
                                                    Vec3d(vertexArr->get(conn[1])), 
                                                    Vec3d(vertexArr->get(conn[2])), 
                                                    &localIntersect);
            }

            if (hitThisFace)
            {
                double distSquared = (ray.origin() - localIntersect).lengthSquared();
                #pragma omp critical
		{
                    if (distSquared < minDistSquared)
                    {
                        *intersectionPoint = localIntersect;
                        minDistSquared = distSquared;

                        if (faceHit)
                        {
                            *faceHit = i + accumulatedFaceCount;
                        }
                    }
                    anyHits = true;
		}
            }
        } // End omp parallel for
        accumulatedFaceCount += numPrimFaces;
    }

    return anyHits;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(OutlineEdgeExtractorTest, SinglePrimitives)
{
    ref<Vec3fArray> va = new Vec3fArray;
    va->reserve(4);
    va->add(Vec3f(0, 0, 0));
    va->add(Vec3f(1, 0, 0));
    va->add(Vec3f(1, 1, 0));
    va->add(Vec3f(0, 1, 0));

    // Point
    {
        const cvf::uint conn[1] = { 0 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(1, conn, 1);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(0, li.size());
    }

    // Line
    {
        const cvf::uint conn[2] = { 0, 1 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(2, conn, 2);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(2, li.size());
        ASSERT_EQ(0, li[0]); 
        ASSERT_EQ(1, li[1]);
    }

    // Tri
    {
        const cvf::uint conn[3] = { 0, 1, 2 };
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(3, conn, 3);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(6, li.size());
        ASSERT_EQ(0, li[0]); 
        ASSERT_EQ(1, li[1]);
        ASSERT_EQ(0, li[2]); 
        ASSERT_EQ(2, li[3]);
        ASSERT_EQ(1, li[4]); 
        ASSERT_EQ(2, li[5]);
    }

    // Quad
    {
        const cvf::uint conn[4] = { 0, 1, 2, 3};
        OutlineEdgeExtractor ee(0, *va);
        ee.addPrimitives(4, conn, 4);

        UIntArray li = *ee.lineIndices();
        ASSERT_EQ(8, li.size());
        ASSERT_EQ(0, li[0]); 
        ASSERT_EQ(1, li[1]);
        ASSERT_EQ(0, li[2]); 
        ASSERT_EQ(3, li[3]);
        ASSERT_EQ(1, li[4]); 
        ASSERT_EQ(2, li[5]);
        ASSERT_EQ(2, li[6]); 
        ASSERT_EQ(3, li[7]);
    }
}