tetprim/GU_PrimTetra.C

/*
 * PROPRIETARY INFORMATION.  This software is proprietary to
 * Side Effects Software Inc., and is not to be reproduced,
 * transmitted, or disclosed in any way without written permission.
 *
 * Produced by:
 *      Jeff Lait
 *      Side Effects Software Inc
 *      477 Richmond Street West
 *      Toronto, Ontario
 *      Canada   M5V 3E7
 *      416-504-9876
 *
 * NAME:        GU_PrimTetra.C ( GU Library, C++)
 *
 * COMMENTS:    Definitions for utility functions of tetrahedrons.
 */

#include "GU_PrimTetra.h"
#include <GA/GA_GBAttributeMath.h>
#include <GEO/GEO_AttributeHandleList.h>
#include <GEO/GEO_WorkVertexBuffer.h>
#include <GU/GU_PrimPoly.h>
#include <GU/GU_ConvertParms.h>
#include <GU/GU_RayIntersect.h>
#include "GT_PrimTetra.h"

using namespace HDK_Sample;

GA_PrimitiveDefinition *GU_PrimTetra::theDef = 0;

GU_PrimTetra *
GU_PrimTetra::build(GU_Detail *gdp, int appendPoints)
{
    GU_PrimTetra       *tet;
    int                     npts;

    tet = (GU_PrimTetra *)gdp->appendPrimitive(GU_PrimTetra::theTypeId());

    npts = tet->getVertexCount();
    if (appendPoints)
    {
        GEO_Primitive *prim = tet;
        for (int i = 0; i < npts; i++)
        {
            prim->getVertexElement(i).setPointOffset(gdp->appendPointOffset());
        }
    }
    return tet; 
}

GU_PrimTetra::~GU_PrimTetra() 
{
}


// Static callback for our factory.
static GA_Primitive *
gu_newPrimTetra(GA_Detail &detail, GA_Offset offset)
{
    return new GU_PrimTetra(static_cast<GU_Detail *>(&detail), offset);
}

void
GU_PrimTetra::registerMyself(GA_PrimitiveFactory *factory)
{
    // Ignore double registration
    if (theDef)
        return;

    theDef = factory->registerDefinition("HDK_Tetrahedron", 
                        gu_newPrimTetra,
                        GA_FAMILY_NONE);
    
    theDef->setLabel("hdk_tetrahedron");
    registerIntrinsics(*theDef);

    // Register the GT tesselation too (now we know what type id we have)
    GT_PrimTetraCollect::registerPrimitive(theDef->getId());
}

int64
GU_PrimTetra::getMemoryUsage() const
{
    exint       mem = sizeof(*this);
    return mem;
}

static GEO_Primitive *
gu_buildPoly(GU_PrimTetra *tet, GU_Detail *gdp, int v1, int v2, int v3,
                bool preserveGroups)
{
    GU_PrimPoly         *poly;

    poly = GU_PrimPoly::build(gdp, 3, 0, 0);

    poly->copyAttributesAndGroups(*tet, preserveGroups);

    gdp->copyVertex((*poly)(0), tet->getVertexElement(v1), 1);
    gdp->copyVertex((*poly)(1), tet->getVertexElement(v2), 1);
    gdp->copyVertex((*poly)(2), tet->getVertexElement(v3), 1);

    return poly;
}

GEO_Primitive *
GU_PrimTetra::convertNew(GU_ConvertParms &parms)
{
    GEO_Primitive       *prim = 0;
    GU_Detail           *gdp = (GU_Detail *)getParent();

    if (parms.toType == GEO_PrimTypeCompat::GEOPRIMPOLY)
    {
        gu_buildPoly(this, gdp, 0, 1, 2, parms.preserveGroups);
        gu_buildPoly(this, gdp, 1, 3, 2, parms.preserveGroups);
        gu_buildPoly(this, gdp, 1, 0, 3, parms.preserveGroups);
        prim = gu_buildPoly(this, gdp, 0, 2, 3, parms.preserveGroups);
    }

    return prim;
}

GEO_Primitive *
GU_PrimTetra::convert(GU_ConvertParms &parms, GA_PointGroup *usedpts)
{
    GEO_Primitive       *prim = convertNew(parms);
    GEO_Detail          *gdp  = getParent();
    GA_PrimitiveGroup   *group;

    if (prim)
    {
        if (usedpts) addPointRefToGroup(*usedpts);
        if (group = parms.getDeletePrimitives())
             group->add(this);
        else gdp->deletePrimitive(*this, !usedpts);
    }
    return prim;
}

void
GU_PrimTetra::normal(NormalComp &output) const
{
    // No need here.
}

void *
GU_PrimTetra::castTo() const
{
    return (GU_Primitive *)this;
}

const GEO_Primitive *
GU_PrimTetra::castToGeo(void) const
{
    return this;
}

GU_RayIntersect *
GU_PrimTetra::createRayCache(int &persistent)
{
    GU_Detail           *gdp    = (GU_Detail *)getParent();
    GU_RayIntersect     *intersect;

    persistent = 0;
    if (gdp->cacheable())
        buildRayCache();

    intersect = getRayCache();
    if (!intersect)
    {
        intersect = new GU_RayIntersect(gdp, this);
        persistent = 1;
    }               

    return intersect;
}

int
GU_PrimTetra::intersectRay(const UT_Vector3 &org, const UT_Vector3 &dir,
                float tmax, float , float *distance, 
                UT_Vector3 *pos, UT_Vector3 *nml, 
                int, float *, float *, int) const
{
    int                 result;
    float               dist;
    UT_BoundingBox      bbox;

    // TODO: Build ray cache and intsrect properly.
    getBBox(&bbox);
    result =  bbox.intersectRay(org, dir, tmax, &dist, nml);
    if (result)
    {
        if (distance) *distance = dist;
        if (pos) *pos = org + dist * dir;
    }
    return result;
}

// This is the usual DSO hook.
extern "C" {
void
newGeometryPrim(GA_PrimitiveFactory *factory)
{
    GU_PrimTetra::registerMyself(factory);
}
}

Generated on Thu Jan 31 00:24:23 2013 for HDK by  doxygen 1.5.9