euclid/GR_Euclid.C

/*
 * Copyright (c) 2013
 *      Side Effects Software Inc.  All rights reserved.
 *
 * Redistribution and use of Houdini Development Kit samples in source and
 * binary forms, with or without modification, are permitted provided that the
 * following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. The name of Side Effects Software may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *----------------------------------------------------------------------------
 */

#include <UT/UT_DSOVersion.h>

#include <RE/RE_Render.h>

#include <GEO/GEO_Primitive.h>

#include <GU/GU_Detail.h>
#include <GU/GU_PrimGroupClosure.h>

#include <GR/GR_Detail.h>
#include <GR/GR_RenderHook.h>
#include <GR/GR_RenderTable.h>
#include <GR/GR_DisplayOption.h>

#include "EUC_Expression.h"
#include "EUC_Object.h"

namespace HDK_Sample {

class GR_Euclid : public GR_RenderHook
{
public:
    GR_Euclid() {}
    virtual ~GR_Euclid() {}

    // Returns the expression associated with the gdp, if any.
    static EUC_Expression       *getExpression(const GU_Detail *gdp);

    void        drawObject(EUC_Object *obj,
                            RE_Render &ren,
                            const GR_DisplayOption *dopt) const;

    virtual void renderWire(GU_Detail *gdp,
                        RE_Render &ren,
                        const GR_AttribOffset &ptinfo,
                        const GR_DisplayOption *dopt,
                        float lod,
                        const GU_PrimGroupClosure *hidden_geometry);

#if defined(HOUDINI_11)
    int          getWireMask(GU_Detail *gdp,
                             const GR_DisplayOption * /*dopt*/) const
    {
        // If we have an expression, don't draw anything
        if (getExpression(gdp))
            return 0;
        else
            return GEOPRIMALL;
    }

    int          getShadedMask(GU_Detail *gdp,
                             const GR_DisplayOption * /*dopt*/) const
    {
        // If we have an expression, don't draw anything
        if (getExpression(gdp))
            return 0;
        else
            return GEOPRIMALL;
    }
#else
    virtual GA_PrimCompat::TypeMask
    getWireMask(GU_Detail *gdp, const GR_DisplayOption * /*dopt*/) const
    {
        // If we have an expression, don't draw anything
        if (getExpression(gdp))
            return GEO_PrimTypeCompat::GEOPRIMNONE;
        else
            return GEO_PrimTypeCompat::GEOPRIMALL;
    }

    virtual GA_PrimCompat::TypeMask
    getShadedMask(GU_Detail *gdp, const GR_DisplayOption * /*dopt*/) const
    {
        // If we have an expression, don't draw anything
        if (getExpression(gdp))
            return GEO_PrimTypeCompat::GEOPRIMNONE;
        else
            return GEO_PrimTypeCompat::GEOPRIMALL;
    }
#endif

    virtual void renderShaded(GU_Detail *gdp,
                        RE_Render &ren,
                        const GR_AttribOffset &ptinfo,
                        const GR_DisplayOption *dopt,
                        float lod,
                        const GU_PrimGroupClosure *hidden_geometry);

    virtual const char *getName() const { return "GR_Euclid"; }
};

} // namespace HDK_Sample

EUC_Expression *
GR_Euclid::getExpression(const GU_Detail *gdp)
{
    int                  euc;
    EUC_Expression      *expr;

#if defined(HOUDINI_11)
    GB_AttributeRef      aoff = gdp->attribs.getOffset("euclid", GB_ATTRIB_INT);
    euc = gdp->attribs().getElement().getValue<int>(aoff);
#else
    GA_ROAttributeRef    aoff = gdp->findIntTuple(GA_ATTRIB_GLOBAL, "euclid",1);
    euc = gdp->element().getValue<int>(aoff);
#endif
    if (aoff.isInvalid())
        return 0;
    
    expr = EUC_Expression::getExprFromUid(euc);
    return expr;
}

void
GR_Euclid::renderWire(GU_Detail *gdp,
                    RE_Render &ren,
                    const GR_AttribOffset & /*ptinfo*/,
                    const GR_DisplayOption *dopt,
                    float /*lod*/,
                    const GU_PrimGroupClosure * /*hidden_geometry*/)
{
    EUC_Expression              *expr;

    expr = getExpression(gdp);
    if (!expr)
        return;

    // We have a valid expression, cook it.
    EUC_ObjectList              objlist;
    int                         i, n;

    expr->evaluate(objlist);

    // Draw each thing...
    n = objlist.entries();
    for (i = 0; i < n; i++)
    {
        drawObject(objlist(i), ren, dopt);
    }
}

void
GR_Euclid::drawObject(EUC_Object *obj,
                        RE_Render &ren,
                        const GR_DisplayOption * /*dopt*/) const
{
    if (!obj)
        return;

    UT_Vector3          cd;
    UT_Color            col;

    if (!obj->getVisible())
        return;

    cd = obj->getColor();
    col.setRGB(cd.x(), cd.y(), cd.z());

    ren.pushColor(col);
    switch (obj->getType())
    {
        case EUC_PointType:
        {
            UT_Vector2          p;
            
            ren.setFont(ren.getViewportSymbolFont(RE_SYMBOL_FONT_SIZE_SMALL));

            p = ((EUC_Point *)obj)->getPos();
            
            ren.textMove3W(p.x(), p.y(), 0);
            ren.putChar(10);

            break;
        }
        case EUC_LineType:
        {
            UT_Vector2          a, b, v, p;

            a = ((EUC_Line *)obj)->getPt(0);
            b = ((EUC_Line *)obj)->getPt(1);
            v = b - a;
            
            // And render that bounding box as wires.
            ren.beginLine();
            p = a - 10*v;
            ren.vertex3DW(p.x(), p.y(), 0);
            ren.vertex3DW(a.x(), a.y(), 0);
            ren.vertex3DW(b.x(), b.y(), 0);
            p = b + 10*v;
            ren.vertex3DW(p.x(), p.y(), 0);
            ren.endLine();
            break;
        }
        case EUC_CircleType:
        {
            float               t, tinc;
            int                 i, npts = 30;
            float               radius;
            UT_Vector2          c, p;

            c = ((EUC_Circle *)obj)->getCenter();
            radius = ((EUC_Circle *)obj)->getRadius();

            ren.beginClosedLine();
            tinc = (float)(2*M_PI) / (float)(npts);
            for (t = 0, i = 0; i < npts; i++, t += tinc)
            {
                p = c;
                p.x() += radius * SYScos(t);
                p.y() += radius * SYSsin(t);
                ren.vertex3DW(p.x(), p.y(), 0);
            }
            ren.endClosedLine();
        }
    }
    ren.popColor();
}

void
GR_Euclid::renderShaded(GU_Detail *gdp,
                    RE_Render &ren,
                    const GR_AttribOffset &ptinfo,
                    const GR_DisplayOption *dopt,
                    float lod,
                    const GU_PrimGroupClosure *hidden_geometry)
{
    // We use the wire render again...
    renderWire(gdp, ren, ptinfo, dopt, lod, hidden_geometry);
}

void
newRenderHook(GR_RenderTable *table)
{
    GR_Euclid *hook = new GR_Euclid;
    
    table->addHook(hook, GR_RENDER_HOOK_VERSION);
}


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