Changeset 3683


Ignore:
Timestamp:
Jun 12, 2013 2:51:11 AM (8 years ago)
Author:
ldelgass
Message:

Improvements to 3D shapes in vtkvis. Add preliminary, experimental grouping.

Location:
trunk/packages/vizservers/vtkvis
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/vtkvis/Arrow.cpp

    r3616 r3683  
    99#include <vtkActor.h>
    1010#include <vtkArrowSource.h>
     11#include <vtkPolyDataNormals.h>
     12#include <vtkReverseSense.h>
    1113
    1214#include "Arrow.h"
     
    3739    }
    3840
     41    vtkSmartPointer<vtkPolyDataNormals> normalFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
     42    normalFilter->SetInputConnection(_arrow->GetOutputPort());
     43    normalFilter->AutoOrientNormalsOff();
     44
    3945    _pdMapper->SetInputConnection(_arrow->GetOutputPort());
    4046
     
    4450    _pdMapper->Update();
    4551}
     52
     53void Arrow::flipNormals(bool state)
     54{
     55    if (_arrow == NULL || _pdMapper == NULL)
     56        return;
     57
     58    if (state) {
     59        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     60        filter->ReverseCellsOn();
     61        filter->ReverseNormalsOn();
     62        filter->SetInputConnection(_arrow->GetOutputPort());
     63
     64        _pdMapper->SetInputConnection(filter->GetOutputPort());
     65    } else {
     66        _pdMapper->SetInputConnection(_arrow->GetOutputPort());
     67    }
     68}
  • trunk/packages/vizservers/vtkvis/Arrow.h

    r3621 r3683  
    5858    }
    5959
     60    /**
     61     * \brief Invert head/tail of arrow
     62     */
    6063    void setInvert(bool state)
    6164    {
     
    6467        }
    6568    }
     69
     70    void flipNormals(bool state);
    6671
    6772private:
  • trunk/packages/vizservers/vtkvis/Box.cpp

    r3616 r3683  
    1515#include <vtkTransform.h>
    1616#include <vtkCubeSource.h>
     17#include <vtkReverseSense.h>
    1718
    1819#include "Box.h"
     
    5051    _pdMapper->Update();
    5152}
     53
     54void Box::flipNormals(bool state)
     55{
     56    if (_box == NULL || _pdMapper == NULL)
     57        return;
     58
     59    if (state) {
     60        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     61        filter->ReverseCellsOn();
     62        filter->ReverseNormalsOn();
     63        filter->SetInputConnection(_box->GetOutputPort());
     64
     65        _pdMapper->SetInputConnection(filter->GetOutputPort());
     66    } else {
     67        _pdMapper->SetInputConnection(_box->GetOutputPort());
     68    }
     69}
  • trunk/packages/vizservers/vtkvis/Box.h

    r3621 r3683  
    4444    }
    4545
     46    void flipNormals(bool state);
     47
    4648private:
    4749    virtual void update();
  • trunk/packages/vizservers/vtkvis/Cone.cpp

    r3616 r3683  
    99#include <vtkActor.h>
    1010#include <vtkConeSource.h>
     11#include <vtkPolyDataNormals.h>
     12#include <vtkReverseSense.h>
    1113
    1214#include "Cone.h"
     
    3739    }
    3840
     41    vtkSmartPointer<vtkPolyDataNormals> normalFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
     42    normalFilter->SetInputConnection(_cone->GetOutputPort());
     43    normalFilter->AutoOrientNormalsOff();
     44
    3945    _pdMapper->SetInputConnection(_cone->GetOutputPort());
    4046
     
    4450    _pdMapper->Update();
    4551}
     52
     53void Cone::flipNormals(bool state)
     54{
     55    if (_cone == NULL || _pdMapper == NULL)
     56        return;
     57
     58    if (state) {
     59        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     60        filter->ReverseCellsOn();
     61        filter->ReverseNormalsOn();
     62        filter->SetInputConnection(_cone->GetOutputPort());
     63
     64        _pdMapper->SetInputConnection(filter->GetOutputPort());
     65    } else {
     66        _pdMapper->SetInputConnection(_cone->GetOutputPort());
     67    }
     68}
  • trunk/packages/vizservers/vtkvis/Cone.h

    r3621 r3683  
    7777    }
    7878
     79    void flipNormals(bool state);
     80
    7981private:
    8082    virtual void update();
  • trunk/packages/vizservers/vtkvis/Cylinder.cpp

    r3680 r3683  
    5353    if (state) {
    5454        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     55        filter->ReverseCellsOn();
     56        filter->ReverseNormalsOn();
    5557        filter->SetInputConnection(_cylinder->GetOutputPort());
    5658
     
    5961        _pdMapper->SetInputConnection(_cylinder->GetOutputPort());
    6062    }
     63    _pdMapper->Update();
    6164}
  • trunk/packages/vizservers/vtkvis/Disk.cpp

    r3680 r3683  
    1010#include <vtkDiskSource.h>
    1111#include <vtkPolyDataNormals.h>
     12#include <vtkReverseSense.h>
    1213
    1314#include "Disk.h"
     
    1718
    1819Disk::Disk() :
    19     Shape(),
    20     _flipNormals(false)
     20    Shape()
    2121{
    2222}
     
    4242    normalFilter->SetInputConnection(_disk->GetOutputPort());
    4343    normalFilter->AutoOrientNormalsOff();
    44     normalFilter->SetFlipNormals(_flipNormals ? 1 : 0);
    4544
    4645    _pdMapper->SetInputConnection(normalFilter->GetOutputPort());
     
    5453void Disk::flipNormals(bool state)
    5554{
    56     if (_flipNormals != state) {
    57         _flipNormals = state;
    58         update();
     55    if (_disk == NULL || _pdMapper == NULL)
     56        return;
     57
     58    if (state) {
     59        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     60        filter->ReverseCellsOn();
     61        filter->ReverseNormalsOn();
     62        filter->SetInputConnection(_disk->GetOutputPort());
     63
     64        _pdMapper->SetInputConnection(filter->GetOutputPort());
     65    } else {
     66        _pdMapper->SetInputConnection(_disk->GetOutputPort());
    5967    }
     68    _pdMapper->Update();
    6069}
  • trunk/packages/vizservers/vtkvis/Disk.h

    r3680 r3683  
    5656    virtual void update();
    5757
    58     bool _flipNormals;
    5958    vtkSmartPointer<vtkDiskSource> _disk;
    6059};
  • trunk/packages/vizservers/vtkvis/GraphicsObject.h

    r3621 r3683  
    4141        CULL_BACK,
    4242        CULL_FRONT_AND_BACK
     43    };
     44    enum ShadingModel {
     45        SHADE_FLAT = VTK_FLAT,
     46        SHADE_GOURAUD = VTK_GOURAUD,
     47        SHADE_PHONG = VTK_PHONG
    4348    };
    4449
     
    701706                } else if (vtkVolume::SafeDownCast(prop) != NULL) {
    702707                    vtkVolume::SafeDownCast(prop)->GetProperty()->SetShade((state ? 1 : 0));
     708                }
     709            }
     710        }
     711    }
     712
     713    /**
     714     * \brief Set shading interpolation model of the prop
     715     */
     716    virtual void setShadingModel(ShadingModel state)
     717    {
     718        if (getActor() != NULL) {
     719            getActor()->GetProperty()->SetInterpolation(state);
     720        } else if (getAssembly() != NULL) {
     721            vtkProp3DCollection *props = getAssembly()->GetParts();
     722            vtkProp3D *prop;
     723            props->InitTraversal();
     724            while ((prop = props->GetNextProp3D()) != NULL) {
     725                if (vtkActor::SafeDownCast(prop) != NULL) {
     726                    vtkActor::SafeDownCast(prop)->GetProperty()->SetInterpolation(state);
    703727                }
    704728            }
  • trunk/packages/vizservers/vtkvis/Group.cpp

    r3621 r3683  
    5454}
    5555
    56 void Group::removeChild(const NodeId& name)
     56GraphicsObject *Group::removeChild(const NodeId& name)
    5757{
    5858    NodeHashmap::iterator itr = _nodes.find(name);
    5959    if (itr == _nodes.end()) {
    6060        ERROR("Node not found: '%s'", name.c_str());
    61         return;
     61        return NULL;
    6262    }
    6363    GraphicsObject *obj = itr->second;
     
    6666    }
    6767    _nodes.erase(itr);
     68    return obj;
    6869}
    6970
  • trunk/packages/vizservers/vtkvis/Group.h

    r3621 r3683  
    5454    }
    5555
    56     void removeChild(const NodeId& name);
     56    GraphicsObject *removeChild(const NodeId& name);
    5757
    5858private:
  • trunk/packages/vizservers/vtkvis/Polygon.cpp

    r3616 r3683  
    99#include <vtkActor.h>
    1010#include <vtkRegularPolygonSource.h>
     11#include <vtkPolyDataNormals.h>
     12#include <vtkReverseSense.h>
    1113
    1214#include "Polygon.h"
     
    3739    }
    3840
     41    vtkSmartPointer<vtkPolyDataNormals> normalFilter = vtkSmartPointer<vtkPolyDataNormals>::New();
     42    normalFilter->SetInputConnection(_polygon->GetOutputPort());
     43    normalFilter->AutoOrientNormalsOff();
     44
    3945    _pdMapper->SetInputConnection(_polygon->GetOutputPort());
    4046
     
    4450    _pdMapper->Update();
    4551}
     52
     53void Polygon::flipNormals(bool state)
     54{
     55    if (_polygon == NULL || _pdMapper == NULL)
     56        return;
     57
     58    if (state) {
     59        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     60        filter->ReverseCellsOn();
     61        filter->ReverseNormalsOn();
     62        filter->SetInputConnection(_polygon->GetOutputPort());
     63
     64        _pdMapper->SetInputConnection(filter->GetOutputPort());
     65    } else {
     66        _pdMapper->SetInputConnection(_polygon->GetOutputPort());
     67    }
     68    _pdMapper->Update();
     69}
     70
  • trunk/packages/vizservers/vtkvis/Polygon.h

    r3621 r3683  
    6363    }
    6464
     65    void flipNormals(bool state);
     66
    6567private:
    6668    virtual void update();
  • trunk/packages/vizservers/vtkvis/RenderServer.h

    r3621 r3683  
    1616class Renderer;
    1717
    18 #define VTKVIS_VERSION_STRING "1.3"
     18#define VTKVIS_VERSION_STRING "1.4"
    1919
    2020#define MSECS_ELAPSED(t1, t2) \
  • trunk/packages/vizservers/vtkvis/Renderer.cpp

    r3680 r3683  
    2020#include <vtkCamera.h>
    2121#include <vtkLight.h>
     22#include <vtkLightCollection.h>
    2223#include <vtkCoordinate.h>
    2324#include <vtkTransform.h>
     
    124125    //_renderer->SetAmbient(.2, .2, .2);
    125126
     127    _renderer->AutomaticLightCreationOff();
     128
    126129    vtkSmartPointer<vtkLight> headlight = vtkSmartPointer<vtkLight>::New();
    127130    headlight->SetLightTypeToHeadlight();
     
    130133    //headlight->SetAmbientColor(1, 1, 1);
    131134    _renderer->AddLight(headlight);
     135
    132136    vtkSmartPointer<vtkLight> skylight = vtkSmartPointer<vtkLight>::New();
    133137    skylight->SetLightTypeToCameraLight();
     
    138142    //skylight->SetAmbientColor(1, 1, 1);
    139143    _renderer->AddLight(skylight);
     144
    140145    _renderer->LightFollowCameraOn();
    141146    _renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
     
    31773182    mergeGraphicsObjectBounds<Disk>(bounds, onlyVisible);
    31783183    mergeGraphicsObjectBounds<Glyphs>(bounds, onlyVisible);
     3184    mergeGraphicsObjectBounds<Group>(bounds, onlyVisible);
    31793185    mergeGraphicsObjectBounds<HeightMap>(bounds, onlyVisible);
    31803186    mergeGraphicsObjectBounds<LIC>(bounds, onlyVisible);
     
    38183824}
    38193825
     3826int Renderer::addLight(float pos[3])
     3827{
     3828    vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();
     3829    light->SetLightTypeToCameraLight();
     3830    light->SetPosition(pos[0], pos[1], pos[2]);
     3831    light->SetFocalPoint(0, 0, 0);
     3832    light->PositionalOff();
     3833    _renderer->AddLight(light);
     3834    _needsRedraw = true;
     3835    return (_renderer->GetLights()->GetNumberOfItems()-1);
     3836}
     3837
     3838vtkLight *Renderer::getLight(int lightIdx)
     3839{
     3840    vtkLightCollection *lights = _renderer->GetLights();
     3841    if (lights->GetNumberOfItems() < lightIdx+1)
     3842        return NULL;
     3843    lights->InitTraversal();
     3844    vtkLight *light = NULL;
     3845    int i = 0;
     3846    do {
     3847        light = lights->GetNextItem();
     3848    } while (i++ < lightIdx);
     3849    return light;
     3850}
     3851
     3852void Renderer::setLightSwitch(int lightIdx, bool state)
     3853{
     3854    vtkLight *light = getLight(lightIdx);
     3855    if (light == NULL) {
     3856        ERROR("Unknown light %d", lightIdx);
     3857        return;
     3858    }
     3859    light->SetSwitch((state ? 1 : 0));
     3860    _needsRedraw = true;
     3861}
     3862
    38203863/**
    38213864 * \brief Initialize the camera zoom region to include the bounding volume given
  • trunk/packages/vizservers/vtkvis/Renderer.h

    r3682 r3683  
    174174    int getWindowHeight() const;
    175175
     176    // Lights
     177
     178    int addLight(float pos[3]);
     179
     180    vtkLight *getLight(int lightIdx);
     181
     182    void setLightSwitch(int lightIdx, bool state);
     183
    176184    // Camera controls
    177185
     
    448456    // Generic GraphicsObject methods
    449457
     458    GraphicsObject *getGenericGraphicsObject(const DataSetId& id);
     459
    450460    template<class T>
    451461    T *getGraphicsObject(const DataSetId& id);
     
    499509
    500510    template<class T>
     511    void setGraphicsObjectOrigin(const DataSetId& id, double origin[3]);
     512
     513    template<class T>
    501514    void setGraphicsObjectPosition(const DataSetId& id, double pos[3]);
    502515
     
    519532
    520533    template<class T>
     534    void setGraphicsObjectCullFace(const DataSetId& id, GraphicsObject::CullFace state);
     535
     536    template<class T>
     537    void setGraphicsObjectCulling(const DataSetId& id, bool state);
     538
     539    template<class T>
    521540    void setGraphicsObjectEdgeVisibility(const DataSetId& id, bool state);
    522541
     
    534553
    535554    template<class T>
     555    void setGraphicsObjectShadingModel(const DataSetId& id, GraphicsObject::ShadingModel state);
     556
     557    template<class T>
    536558    void setGraphicsObjectSpecular(const DataSetId& id, double coeff, double power);
    537559
     
    548570    void setGraphicsObjectWireframe(const DataSetId& id, bool state);
    549571
     572    // For Shapes:
     573
     574    template<class T>
     575    void setGraphicsObjectFlipNormals(const DataSetId& id, bool state);
     576
    550577    // Arcs
    551578
    552     bool addArc(const DataSetId& id, double pt1[3], double pt2[3]);
     579    bool addArc(const DataSetId& id, double center[3], double pt1[3], double pt2[3]);
    553580
    554581    void setArcResolution(const DataSetId& id, int res);
     
    556583    // Arrows
    557584
    558     bool addArrow(const DataSetId& id, double tipRadius, double shaftRadius, double tipLength);
     585    bool addArrow(const DataSetId& id, double tipRadius, double shaftRadius, double tipLength, bool flipNormals = false);
    559586
    560587    void setArrowResolution(const DataSetId& id, int resTip, int resShaft);
    561588
     589    // Boxes
     590
     591    bool addBox(const DataSetId& id, double xLen, double yLen, double zLen, bool flipNormals = false);
     592
    562593    // Cones
    563594
    564     bool addCone(const DataSetId& id, double radius, double height, bool cap);
     595    bool addCone(const DataSetId& id, double radius, double height, bool cap, bool flipNormals = false);
    565596
    566597    void setConeResolution(const DataSetId& id, int res);
     
    628659    // Cylinders
    629660
    630     bool addCylinder(const DataSetId& id, double radius, double height, bool cap);
     661    bool addCylinder(const DataSetId& id, double radius, double height, bool cap, bool flipNormals = false);
     662
     663    void setCylinderCapping(const DataSetId& id, bool state);
    631664
    632665    void setCylinderResolution(const DataSetId& id, int res);
     
    634667    // Disks
    635668
    636     bool addDisk(const DataSetId& id, double innerRadius, double outerRadius);
     669    bool addDisk(const DataSetId& id, double innerRadius, double outerRadius, bool flipNormals = false);
    637670
    638671    void setDiskResolution(const DataSetId& id, int resRadial, int resCircum);
     
    660693    void setGlyphsScaleFactor(const DataSetId& id, double scale);
    661694
     695    // Groups
     696
     697    bool addGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList);
     698
     699    void addChildrenToGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList);
     700
     701    void removeChildrenFromGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList);
     702
    662703    // Height maps
    663704
     
    732773    // N-sided Regular Polygons
    733774
    734     bool addPolygon(const DataSetId& id, int numSides);
     775    bool addPolygon(const DataSetId& id, int numSides, double center[3], double normal[3], double radius);
    735776
    736777    // PolyData meshes
     
    755796    // Spheres
    756797
    757     void setSphereSection(const DataSetId& id, double thetaStart, double thetaEnd,
     798    bool addSphere(const DataSetId& id, double center[3], double radius, bool flipNormals = false);
     799
     800    void setSphereSection(const DataSetId& id,
     801                          double thetaStart, double thetaEnd,
    758802                          double phiStart, double phiEnd);
    759803
  • trunk/packages/vizservers/vtkvis/RendererCmd.cpp

    r3682 r3683  
    131131         Tcl_Obj *const *objv)
    132132{
    133     double pt1[3];
    134     double pt2[3];
    135     if (Tcl_GetDoubleFromObj(interp, objv[2], &pt1[0]) != TCL_OK ||
    136         Tcl_GetDoubleFromObj(interp, objv[3], &pt1[1]) != TCL_OK ||
    137         Tcl_GetDoubleFromObj(interp, objv[4], &pt1[2]) != TCL_OK ||
    138         Tcl_GetDoubleFromObj(interp, objv[5], &pt2[0]) != TCL_OK ||
    139         Tcl_GetDoubleFromObj(interp, objv[6], &pt2[1]) != TCL_OK ||
    140         Tcl_GetDoubleFromObj(interp, objv[7], &pt2[2]) != TCL_OK) {
    141         return TCL_ERROR;
    142     }
    143     const char *name = Tcl_GetString(objv[8]);
    144     if (!g_renderer->addArc(name, pt1, pt2)) {
     133    double center[3], pt1[3], pt2[3];
     134    if (Tcl_GetDoubleFromObj(interp, objv[2], &center[0]) != TCL_OK ||
     135        Tcl_GetDoubleFromObj(interp, objv[3], &center[1]) != TCL_OK ||
     136        Tcl_GetDoubleFromObj(interp, objv[4], &center[2]) != TCL_OK ||
     137        Tcl_GetDoubleFromObj(interp, objv[5], &pt1[0]) != TCL_OK ||
     138        Tcl_GetDoubleFromObj(interp, objv[6], &pt1[1]) != TCL_OK ||
     139        Tcl_GetDoubleFromObj(interp, objv[7], &pt1[2]) != TCL_OK ||
     140        Tcl_GetDoubleFromObj(interp, objv[8], &pt2[0]) != TCL_OK ||
     141        Tcl_GetDoubleFromObj(interp, objv[9], &pt2[1]) != TCL_OK ||
     142        Tcl_GetDoubleFromObj(interp, objv[10], &pt2[2]) != TCL_OK) {
     143        return TCL_ERROR;
     144    }
     145    const char *name = Tcl_GetString(objv[11]);
     146    if (!g_renderer->addArc(name, center, pt1, pt2)) {
    145147        Tcl_AppendResult(interp, "Failed to create arc", (char*)NULL);
    146148        return TCL_ERROR;
     
    236238
    237239static int
     240ArcOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     241            Tcl_Obj *const *objv)
     242{
     243    double origin[3];
     244    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     245        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     246        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     247        return TCL_ERROR;
     248    }
     249    if (objc == 6) {
     250        const char *name = Tcl_GetString(objv[5]);
     251        g_renderer->setGraphicsObjectOrigin<Arc>(name, origin);
     252    } else {
     253        g_renderer->setGraphicsObjectOrigin<Arc>("all", origin);
     254    }
     255    return TCL_OK;
     256}
     257
     258static int
    238259ArcPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    239260              Tcl_Obj *const *objv)
     
    308329
    309330static Rappture::CmdSpec arcOps[] = {
    310     {"add",       1, ArcAddOp, 9, 9, "x1 y1 z1 x2 y2 z2 name"},
     331    {"add",       1, ArcAddOp, 12, 12, "centerX centerY centerZ x1 y1 z1 x2 y2 z2 name"},
    311332    {"color",     1, ArcColorOp, 5, 6, "r g b ?name?"},
    312333    {"delete",    1, ArcDeleteOp, 2, 3, "?name?"},
     
    314335    {"linewidth", 5, ArcLineWidthOp, 3, 4, "width ?name?"},
    315336    {"opacity",   2, ArcOpacityOp, 3, 4, "value ?name?"},
    316     {"orient",    2, ArcOrientOp, 6, 7, "qw qx qy qz ?name?"},
     337    {"orient",    4, ArcOrientOp, 6, 7, "qw qx qy qz ?name?"},
     338    {"origin",    4, ArcOriginOp, 5, 6, "x y z ?name?"},
    317339    {"pos",       2, ArcPositionOp, 5, 6, "x y z ?name?"},
    318340    {"resolution",1, ArcResolutionOp, 3, 4, "res ?name?"},
     
    387409
    388410static int
     411ArrowCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     412               Tcl_Obj *const *objv)
     413{
     414    bool state;
     415    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     416        return TCL_ERROR;
     417    }
     418    if (objc == 4) {
     419        const char *name = Tcl_GetString(objv[3]);
     420        g_renderer->setGraphicsObjectCulling<Arrow>(name, state);
     421    } else {
     422        g_renderer->setGraphicsObjectCulling<Arrow>("all", state);
     423    }
     424    return TCL_OK;
     425}
     426
     427static int
    389428ArrowEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    390429                      Tcl_Obj *const *objv)
     
    399438    } else {
    400439        g_renderer->setGraphicsObjectEdgeVisibility<Arrow>("all", state);
     440    }
     441    return TCL_OK;
     442}
     443
     444static int
     445ArrowFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     446                   Tcl_Obj *const *objv)
     447{
     448    bool state;
     449    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     450        return TCL_ERROR;
     451    }
     452    if (objc == 4) {
     453        const char *name = Tcl_GetString(objv[3]);
     454        g_renderer->setGraphicsObjectFlipNormals<Arrow>(name, state);
     455    } else {
     456        g_renderer->setGraphicsObjectFlipNormals<Arrow>("all", state);
    401457    }
    402458    return TCL_OK;
     
    519575
    520576static int
     577ArrowOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     578              Tcl_Obj *const *objv)
     579{
     580    double origin[3];
     581    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     582        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     583        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     584        return TCL_ERROR;
     585    }
     586    if (objc == 6) {
     587        const char *name = Tcl_GetString(objv[5]);
     588        g_renderer->setGraphicsObjectOrigin<Arrow>(name, origin);
     589    } else {
     590        g_renderer->setGraphicsObjectOrigin<Arrow>("all", origin);
     591    }
     592    return TCL_OK;
     593}
     594
     595static int
    521596ArrowPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    522597                Tcl_Obj *const *objv)
     
    575650
    576651static int
     652ArrowShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     653               Tcl_Obj *const *objv)
     654{
     655    GraphicsObject::ShadingModel shadeModel;
     656    const char *str = Tcl_GetString(objv[2]);
     657    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     658        shadeModel = GraphicsObject::SHADE_FLAT;
     659    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     660        shadeModel = GraphicsObject::SHADE_GOURAUD;
     661    } else {
     662         Tcl_AppendResult(interp, "bad shading option \"", str,
     663                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     664        return TCL_ERROR;
     665    }
     666    if (objc == 4) {
     667        const char *name = Tcl_GetString(objv[3]);
     668        g_renderer->setGraphicsObjectShadingModel<Arrow>(name, shadeModel);
     669    } else {
     670        g_renderer->setGraphicsObjectShadingModel<Arrow>("all", shadeModel);
     671    }
     672    return TCL_OK;
     673}
     674
     675static int
    577676ArrowVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    578677               Tcl_Obj *const *objv)
     
    610709static Rappture::CmdSpec arrowOps[] = {
    611710    {"add",       1, ArrowAddOp, 6, 6, "tipRadius shaftRadius tipLength name"},
    612     {"color",     1, ArrowColorOp, 5, 6, "r g b ?name?"},
     711    {"color",     2, ArrowColorOp, 5, 6, "r g b ?name?"},
     712    {"culling",   2, ArrowCullingOp, 3, 4, "bool ?name?"},
    613713    {"delete",    1, ArrowDeleteOp, 2, 3, "?name?"},
    614714    {"edges",     1, ArrowEdgeVisibilityOp, 3, 4, "bool ?name?"},
     715    {"flipnorms", 1, ArrowFlipNormalsOp, 3, 4, "bool ?name?"},
    615716    {"lighting",  3, ArrowLightingOp, 3, 4, "bool ?name?"},
    616717    {"linecolor", 5, ArrowLineColorOp, 5, 6, "r g b ?name?"},
     
    618719    {"material",  1, ArrowMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    619720    {"opacity",   2, ArrowOpacityOp, 3, 4, "value ?name?"},
    620     {"orient",    2, ArrowOrientOp, 6, 7, "qw qx qy qz ?name?"},
     721    {"orient",    4, ArrowOrientOp, 6, 7, "qw qx qy qz ?name?"},
     722    {"origin",    4, ArrowOriginOp, 5, 6, "x y z ?name?"},
    621723    {"pos",       2, ArrowPositionOp, 5, 6, "x y z ?name?"},
    622724    {"resolution",1, ArrowResolutionOp, 4, 5, "tipRes shaftRes ?name?"},
    623     {"scale",     1, ArrowScaleOp, 5, 6, "sx sy sz ?name?"},
     725    {"scale",     2, ArrowScaleOp, 5, 6, "sx sy sz ?name?"},
     726    {"shading",   2, ArrowShadingOp, 3, 4, "val ?name?"},
    624727    {"visible",   1, ArrowVisibleOp, 3, 4, "bool ?name?"},
    625728    {"wireframe", 1, ArrowWireframeOp, 3, 4, "bool ?name?"}
     
    16031706         Tcl_Obj *const *objv)
    16041707{
    1605     const char *name = Tcl_GetString(objv[2]);
    1606     if (!g_renderer->addGraphicsObject<Box>(name)) {
     1708    double xLen, yLen, zLen;
     1709    if (Tcl_GetDoubleFromObj(interp, objv[2], &xLen) != TCL_OK ||
     1710        Tcl_GetDoubleFromObj(interp, objv[3], &yLen) != TCL_OK ||
     1711        Tcl_GetDoubleFromObj(interp, objv[4], &zLen) != TCL_OK) {
     1712        return TCL_ERROR;
     1713    }
     1714    const char *name = Tcl_GetString(objv[5]);
     1715    if (!g_renderer->addBox(name, xLen, yLen, zLen)) {
    16071716        Tcl_AppendResult(interp, "Failed to create box", (char*)NULL);
    16081717        return TCL_ERROR;
     
    16441753
    16451754static int
     1755BoxCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     1756             Tcl_Obj *const *objv)
     1757{
     1758    bool state;
     1759    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     1760        return TCL_ERROR;
     1761    }
     1762    if (objc == 4) {
     1763        const char *name = Tcl_GetString(objv[3]);
     1764        g_renderer->setGraphicsObjectCulling<Box>(name, state);
     1765    } else {
     1766        g_renderer->setGraphicsObjectCulling<Box>("all", state);
     1767    }
     1768    return TCL_OK;
     1769}
     1770
     1771static int
    16461772BoxEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    16471773                    Tcl_Obj *const *objv)
     
    16561782    } else {
    16571783        g_renderer->setGraphicsObjectEdgeVisibility<Box>("all", state);
     1784    }
     1785    return TCL_OK;
     1786}
     1787
     1788static int
     1789BoxFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     1790                 Tcl_Obj *const *objv)
     1791{
     1792    bool state;
     1793    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     1794        return TCL_ERROR;
     1795    }
     1796    if (objc == 4) {
     1797        const char *name = Tcl_GetString(objv[3]);
     1798        g_renderer->setGraphicsObjectFlipNormals<Box>(name, state);
     1799    } else {
     1800        g_renderer->setGraphicsObjectFlipNormals<Box>("all", state);
    16581801    }
    16591802    return TCL_OK;
     
    17761919
    17771920static int
     1921BoxOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     1922            Tcl_Obj *const *objv)
     1923{
     1924    double origin[3];
     1925    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     1926        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     1927        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     1928        return TCL_ERROR;
     1929    }
     1930    if (objc == 6) {
     1931        const char *name = Tcl_GetString(objv[5]);
     1932        g_renderer->setGraphicsObjectOrigin<Box>(name, origin);
     1933    } else {
     1934        g_renderer->setGraphicsObjectOrigin<Box>("all", origin);
     1935    }
     1936    return TCL_OK;
     1937}
     1938
     1939static int
    17781940BoxPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    17791941              Tcl_Obj *const *objv)
     
    18141976
    18151977static int
     1978BoxShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     1979             Tcl_Obj *const *objv)
     1980{
     1981    GraphicsObject::ShadingModel shadeModel;
     1982    const char *str = Tcl_GetString(objv[2]);
     1983    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     1984        shadeModel = GraphicsObject::SHADE_FLAT;
     1985    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     1986        shadeModel = GraphicsObject::SHADE_GOURAUD;
     1987    } else {
     1988         Tcl_AppendResult(interp, "bad shading option \"", str,
     1989                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     1990        return TCL_ERROR;
     1991    }
     1992    if (objc == 4) {
     1993        const char *name = Tcl_GetString(objv[3]);
     1994        g_renderer->setGraphicsObjectShadingModel<Box>(name, shadeModel);
     1995    } else {
     1996        g_renderer->setGraphicsObjectShadingModel<Box>("all", shadeModel);
     1997    }
     1998    return TCL_OK;
     1999}
     2000
     2001static int
    18162002BoxVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    18172003             Tcl_Obj *const *objv)
     
    18482034
    18492035static Rappture::CmdSpec boxOps[] = {
    1850     {"add",       1, BoxAddOp, 3, 3, "name"},
    1851     {"color",     1, BoxColorOp, 5, 6, "r g b ?name?"},
     2036    {"add",       1, BoxAddOp, 6, 6, "xLen yLen zLen name"},
     2037    {"color",     2, BoxColorOp, 5, 6, "r g b ?name?"},
     2038    {"culling",   2, BoxCullingOp, 3, 4, "bool ?name?"},
    18522039    {"delete",    1, BoxDeleteOp, 2, 3, "?name?"},
    18532040    {"edges",     1, BoxEdgeVisibilityOp, 3, 4, "bool ?name?"},
     2041    {"flipnorms", 1, BoxFlipNormalsOp, 3, 4, "bool ?name?"},
    18542042    {"lighting",  3, BoxLightingOp, 3, 4, "bool ?name?"},
    18552043    {"linecolor", 5, BoxLineColorOp, 5, 6, "r g b ?name?"},
     
    18572045    {"material",  1, BoxMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    18582046    {"opacity",   2, BoxOpacityOp, 3, 4, "value ?name?"},
    1859     {"orient",    2, BoxOrientOp, 6, 7, "qw qx qy qz ?name?"},
     2047    {"orient",    4, BoxOrientOp, 6, 7, "qw qx qy qz ?name?"},
     2048    {"origin",    4, BoxOriginOp, 5, 6, "x y z ?name?"},
    18602049    {"pos",       2, BoxPositionOp, 5, 6, "x y z ?name?"},
    1861     {"scale",     1, BoxScaleOp, 5, 6, "sx sy sz ?name?"},
     2050    {"scale",     2, BoxScaleOp, 5, 6, "sx sy sz ?name?"},
     2051    {"shading",   2, BoxShadingOp, 3, 4, "val ?name?"},
    18622052    {"visible",   1, BoxVisibleOp, 3, 4, "bool ?name?"},
    18632053    {"wireframe", 1, BoxWireframeOp, 3, 4, "bool ?name?"}
     
    23882578
    23892579static int
     2580ConeCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2581              Tcl_Obj *const *objv)
     2582{
     2583    bool state;
     2584    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     2585        return TCL_ERROR;
     2586    }
     2587    if (objc == 4) {
     2588        const char *name = Tcl_GetString(objv[3]);
     2589        g_renderer->setGraphicsObjectCulling<Cone>(name, state);
     2590    } else {
     2591        g_renderer->setGraphicsObjectCulling<Cone>("all", state);
     2592    }
     2593    return TCL_OK;
     2594}
     2595
     2596static int
    23902597ConeEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    23912598                     Tcl_Obj *const *objv)
     
    24002607    } else {
    24012608        g_renderer->setGraphicsObjectEdgeVisibility<Cone>("all", state);
     2609    }
     2610    return TCL_OK;
     2611}
     2612
     2613static int
     2614ConeFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2615                 Tcl_Obj *const *objv)
     2616{
     2617    bool state;
     2618    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     2619        return TCL_ERROR;
     2620    }
     2621    if (objc == 4) {
     2622        const char *name = Tcl_GetString(objv[3]);
     2623        g_renderer->setGraphicsObjectFlipNormals<Cone>(name, state);
     2624    } else {
     2625        g_renderer->setGraphicsObjectFlipNormals<Cone>("all", state);
    24022626    }
    24032627    return TCL_OK;
     
    25202744
    25212745static int
     2746ConeOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2747             Tcl_Obj *const *objv)
     2748{
     2749    double origin[3];
     2750    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     2751        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     2752        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     2753        return TCL_ERROR;
     2754    }
     2755    if (objc == 6) {
     2756        const char *name = Tcl_GetString(objv[5]);
     2757        g_renderer->setGraphicsObjectOrigin<Cone>(name, origin);
     2758    } else {
     2759        g_renderer->setGraphicsObjectOrigin<Cone>("all", origin);
     2760    }
     2761    return TCL_OK;
     2762}
     2763
     2764static int
    25222765ConePositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    25232766               Tcl_Obj *const *objv)
     
    25752818
    25762819static int
     2820ConeShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2821              Tcl_Obj *const *objv)
     2822{
     2823    GraphicsObject::ShadingModel shadeModel;
     2824    const char *str = Tcl_GetString(objv[2]);
     2825    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     2826        shadeModel = GraphicsObject::SHADE_FLAT;
     2827    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     2828        shadeModel = GraphicsObject::SHADE_GOURAUD;
     2829    } else {
     2830         Tcl_AppendResult(interp, "bad shading option \"", str,
     2831                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     2832        return TCL_ERROR;
     2833    }
     2834    if (objc == 4) {
     2835        const char *name = Tcl_GetString(objv[3]);
     2836        g_renderer->setGraphicsObjectShadingModel<Cone>(name, shadeModel);
     2837    } else {
     2838        g_renderer->setGraphicsObjectShadingModel<Cone>("all", shadeModel);
     2839    }
     2840    return TCL_OK;
     2841}
     2842
     2843static int
    25772844ConeVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    25782845              Tcl_Obj *const *objv)
     
    26102877static Rappture::CmdSpec coneOps[] = {
    26112878    {"add",       1, ConeAddOp, 6, 6, "radius height cap name"},
    2612     {"color",     1, ConeColorOp, 5, 6, "r g b ?name?"},
     2879    {"color",     2, ConeColorOp, 5, 6, "r g b ?name?"},
     2880    {"culling",   2, ConeCullingOp, 3, 4, "bool ?name?"},
    26132881    {"delete",    1, ConeDeleteOp, 2, 3, "?name?"},
    26142882    {"edges",     1, ConeEdgeVisibilityOp, 3, 4, "bool ?name?"},
     2883    {"flipnorms", 1, ConeFlipNormalsOp, 3, 4, "bool ?name?"},
    26152884    {"lighting",  3, ConeLightingOp, 3, 4, "bool ?name?"},
    26162885    {"linecolor", 5, ConeLineColorOp, 5, 6, "r g b ?name?"},
     
    26182887    {"material",  1, ConeMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    26192888    {"opacity",   2, ConeOpacityOp, 3, 4, "value ?name?"},
    2620     {"orient",    2, ConeOrientOp, 6, 7, "qw qx qy qz ?name?"},
     2889    {"orient",    4, ConeOrientOp, 6, 7, "qw qx qy qz ?name?"},
     2890    {"origin",    4, ConeOriginOp, 5, 6, "x y z ?name?"},
    26212891    {"pos",       2, ConePositionOp, 5, 6, "x y z ?name?"},
    26222892    {"resolution",1, ConeResolutionOp, 3, 4, "res ?name?"},
    2623     {"scale",     1, ConeScaleOp, 5, 6, "sx sy sz ?name?"},
     2893    {"scale",     2, ConeScaleOp, 5, 6, "sx sy sz ?name?"},
     2894    {"shading",   2, ConeShadingOp, 3, 4, "val ?name?"},
    26242895    {"visible",   1, ConeVisibleOp, 3, 4, "bool ?name?"},
    26252896    {"wireframe", 1, ConeWireframeOp, 3, 4, "bool ?name?"}
     
    39344205
    39354206static int
     4207CylinderCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     4208                  Tcl_Obj *const *objv)
     4209{
     4210    bool state;
     4211    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     4212        return TCL_ERROR;
     4213    }
     4214    if (objc == 4) {
     4215        const char *name = Tcl_GetString(objv[3]);
     4216        g_renderer->setGraphicsObjectCulling<Cylinder>(name, state);
     4217    } else {
     4218        g_renderer->setGraphicsObjectCulling<Cylinder>("all", state);
     4219    }
     4220    return TCL_OK;
     4221}
     4222
     4223static int
    39364224CylinderEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    39374225                         Tcl_Obj *const *objv)
     
    39464234    } else {
    39474235        g_renderer->setGraphicsObjectEdgeVisibility<Cylinder>("all", state);
     4236    }
     4237    return TCL_OK;
     4238}
     4239
     4240static int
     4241CylinderFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     4242                 Tcl_Obj *const *objv)
     4243{
     4244    bool state;
     4245    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     4246        return TCL_ERROR;
     4247    }
     4248    if (objc == 4) {
     4249        const char *name = Tcl_GetString(objv[3]);
     4250        g_renderer->setGraphicsObjectFlipNormals<Cylinder>(name, state);
     4251    } else {
     4252        g_renderer->setGraphicsObjectFlipNormals<Cylinder>("all", state);
    39484253    }
    39494254    return TCL_OK;
     
    40664371
    40674372static int
     4373CylinderOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     4374                 Tcl_Obj *const *objv)
     4375{
     4376    double origin[3];
     4377    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     4378        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     4379        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     4380        return TCL_ERROR;
     4381    }
     4382    if (objc == 6) {
     4383        const char *name = Tcl_GetString(objv[5]);
     4384        g_renderer->setGraphicsObjectOrigin<Cylinder>(name, origin);
     4385    } else {
     4386        g_renderer->setGraphicsObjectOrigin<Cylinder>("all", origin);
     4387    }
     4388    return TCL_OK;
     4389}
     4390
     4391static int
    40684392CylinderPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    40694393                   Tcl_Obj *const *objv)
     
    41214445
    41224446static int
     4447CylinderShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     4448                  Tcl_Obj *const *objv)
     4449{
     4450    GraphicsObject::ShadingModel shadeModel;
     4451    const char *str = Tcl_GetString(objv[2]);
     4452    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     4453        shadeModel = GraphicsObject::SHADE_FLAT;
     4454    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     4455        shadeModel = GraphicsObject::SHADE_GOURAUD;
     4456    } else {
     4457         Tcl_AppendResult(interp, "bad shading option \"", str,
     4458                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     4459        return TCL_ERROR;
     4460    }
     4461    if (objc == 4) {
     4462        const char *name = Tcl_GetString(objv[3]);
     4463        g_renderer->setGraphicsObjectShadingModel<Cylinder>(name, shadeModel);
     4464    } else {
     4465        g_renderer->setGraphicsObjectShadingModel<Cylinder>("all", shadeModel);
     4466    }
     4467    return TCL_OK;
     4468}
     4469
     4470static int
    41234471CylinderVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    41244472                  Tcl_Obj *const *objv)
     
    41554503
    41564504static Rappture::CmdSpec cylinderOps[] = {
    4157     {"add",       1, CylinderAddOp, 6, 6, " radius height cap name"},
    4158     {"color",     1, CylinderColorOp, 5, 6, "r g b ?name?"},
     4505    {"add",       1, CylinderAddOp, 6, 6, "radius height cap name"},
     4506    {"color",     2, CylinderColorOp, 5, 6, "r g b ?name?"},
     4507    {"culling",   2, CylinderCullingOp, 3, 4, "bool ?name?"},
    41594508    {"delete",    1, CylinderDeleteOp, 2, 3, "?name?"},
    41604509    {"edges",     1, CylinderEdgeVisibilityOp, 3, 4, "bool ?name?"},
     4510    {"flipnorms", 1, CylinderFlipNormalsOp, 3, 4, "bool ?name?"},
    41614511    {"lighting",  3, CylinderLightingOp, 3, 4, "bool ?name?"},
    41624512    {"linecolor", 5, CylinderLineColorOp, 5, 6, "r g b ?name?"},
     
    41644514    {"material",  1, CylinderMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    41654515    {"opacity",   2, CylinderOpacityOp, 3, 4, "value ?name?"},
    4166     {"orient",    2, CylinderOrientOp, 6, 7, "qw qx qy qz ?name?"},
     4516    {"orient",    4, CylinderOrientOp, 6, 7, "qw qx qy qz ?name?"},
     4517    {"origin",    4, CylinderOriginOp, 5, 6, "x y z ?name?"},
    41674518    {"pos",       2, CylinderPositionOp, 5, 6, "x y z ?name?"},
    41684519    {"resolution",1, CylinderResolutionOp, 3, 4, "res ?name?"},
    4169     {"scale",     1, CylinderScaleOp, 5, 6, "sx sy sz ?name?"},
     4520    {"scale",     2, CylinderScaleOp, 5, 6, "sx sy sz ?name?"},
     4521    {"shading",   2, CylinderShadingOp, 3, 4, "val ?name?"},
    41704522    {"visible",   1, CylinderVisibleOp, 3, 4, "bool ?name?"},
    41714523    {"wireframe", 1, CylinderWireframeOp, 3, 4, "bool ?name?"}
     
    46685020
    46695021static int
     5022DiskCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5023              Tcl_Obj *const *objv)
     5024{
     5025    bool state;
     5026    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     5027        return TCL_ERROR;
     5028    }
     5029    if (objc == 4) {
     5030        const char *name = Tcl_GetString(objv[3]);
     5031        g_renderer->setGraphicsObjectCulling<Disk>(name, state);
     5032    } else {
     5033        g_renderer->setGraphicsObjectCulling<Disk>("all", state);
     5034    }
     5035    return TCL_OK;
     5036}
     5037
     5038static int
    46705039DiskEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    46715040                     Tcl_Obj *const *objv)
     
    46805049    } else {
    46815050        g_renderer->setGraphicsObjectEdgeVisibility<Disk>("all", state);
     5051    }
     5052    return TCL_OK;
     5053}
     5054
     5055static int
     5056DiskFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5057                 Tcl_Obj *const *objv)
     5058{
     5059    bool state;
     5060    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     5061        return TCL_ERROR;
     5062    }
     5063    if (objc == 4) {
     5064        const char *name = Tcl_GetString(objv[3]);
     5065        g_renderer->setGraphicsObjectFlipNormals<Disk>(name, state);
     5066    } else {
     5067        g_renderer->setGraphicsObjectFlipNormals<Disk>("all", state);
    46825068    }
    46835069    return TCL_OK;
     
    48005186
    48015187static int
     5188DiskOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5189             Tcl_Obj *const *objv)
     5190{
     5191    double origin[3];
     5192    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     5193        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     5194        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     5195        return TCL_ERROR;
     5196    }
     5197    if (objc == 6) {
     5198        const char *name = Tcl_GetString(objv[5]);
     5199        g_renderer->setGraphicsObjectOrigin<Disk>(name, origin);
     5200    } else {
     5201        g_renderer->setGraphicsObjectOrigin<Disk>("all", origin);
     5202    }
     5203    return TCL_OK;
     5204}
     5205
     5206static int
    48025207DiskPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    48035208               Tcl_Obj *const *objv)
     
    48565261
    48575262static int
     5263DiskShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5264              Tcl_Obj *const *objv)
     5265{
     5266    GraphicsObject::ShadingModel shadeModel;
     5267    const char *str = Tcl_GetString(objv[2]);
     5268    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     5269        shadeModel = GraphicsObject::SHADE_FLAT;
     5270    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     5271        shadeModel = GraphicsObject::SHADE_GOURAUD;
     5272    } else {
     5273         Tcl_AppendResult(interp, "bad shading option \"", str,
     5274                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     5275        return TCL_ERROR;
     5276    }
     5277    if (objc == 4) {
     5278        const char *name = Tcl_GetString(objv[3]);
     5279        g_renderer->setGraphicsObjectShadingModel<Disk>(name, shadeModel);
     5280    } else {
     5281        g_renderer->setGraphicsObjectShadingModel<Disk>("all", shadeModel);
     5282    }
     5283    return TCL_OK;
     5284}
     5285
     5286static int
    48585287DiskVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    48595288              Tcl_Obj *const *objv)
     
    48915320static Rappture::CmdSpec diskOps[] = {
    48925321    {"add",       1, DiskAddOp, 5, 5, "innerRadius outerRadius name"},
    4893     {"color",     1, DiskColorOp, 5, 6, "r g b ?name?"},
     5322    {"color",     2, DiskColorOp, 5, 6, "r g b ?name?"},
     5323    {"culling",   2, DiskCullingOp, 3, 4, "bool ?name?"},
    48945324    {"delete",    1, DiskDeleteOp, 2, 3, "?name?"},
    48955325    {"edges",     1, DiskEdgeVisibilityOp, 3, 4, "bool ?name?"},
     5326    {"flipnorms", 1, DiskFlipNormalsOp, 3, 4, "bool ?name?"},
    48965327    {"lighting",  3, DiskLightingOp, 3, 4, "bool ?name?"},
    48975328    {"linecolor", 5, DiskLineColorOp, 5, 6, "r g b ?name?"},
     
    48995330    {"material",  1, DiskMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    49005331    {"opacity",   2, DiskOpacityOp, 3, 4, "value ?name?"},
    4901     {"orient",    2, DiskOrientOp, 6, 7, "qw qx qy qz ?name?"},
     5332    {"orient",    4, DiskOrientOp, 6, 7, "qw qx qy qz ?name?"},
     5333    {"origin",    4, DiskOriginOp, 5, 6, "x y z ?name?"},
    49025334    {"pos",       2, DiskPositionOp, 5, 6, "x y z ?name?"},
    49035335    {"resolution",1, DiskResolutionOp, 4, 5, "resRadial resCircum ?name?"},
    4904     {"scale",     1, DiskScaleOp, 5, 6, "sx sy sz ?name?"},
     5336    {"scale",     2, DiskScaleOp, 5, 6, "sx sy sz ?name?"},
     5337    {"shading",   2, DiskShadingOp, 3, 4, "val ?name?"},
    49055338    {"visible",   1, DiskVisibleOp, 3, 4, "bool ?name?"},
    49065339    {"wireframe", 1, DiskWireframeOp, 3, 4, "bool ?name?"}
     
    54075840
    54085841    proc = Rappture::GetOpFromObj(interp, nGlyphsOps, glyphsOps,
     5842                                  Rappture::CMDSPEC_ARG1, objc, objv, 0);
     5843    if (proc == NULL) {
     5844        return TCL_ERROR;
     5845    }
     5846    return (*proc) (clientData, interp, objc, objv);
     5847}
     5848
     5849static int
     5850GroupAddOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5851           Tcl_Obj *const *objv)
     5852{
     5853    int numNodes;
     5854    Tcl_Obj **nodes = NULL;
     5855    if (Tcl_ListObjGetElements(interp, objv[2], &numNodes, &nodes) != TCL_OK) {
     5856        return TCL_ERROR;
     5857    }
     5858    std::vector<Group::NodeId> nodeList;
     5859    for (int i = 0; i < numNodes; i++) {
     5860        nodeList.push_back(Tcl_GetString(nodes[i]));
     5861    }
     5862    const char *name = Tcl_GetString(objv[3]);
     5863    if (!g_renderer->addGroup(name, nodeList)) {
     5864        Tcl_AppendResult(interp, "Failed to create group", (char*)NULL);
     5865        return TCL_ERROR;
     5866    }
     5867    return TCL_OK;
     5868}
     5869
     5870static int
     5871GroupDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5872              Tcl_Obj *const *objv)
     5873{
     5874    if (objc == 3) {
     5875        const char *name = Tcl_GetString(objv[2]);
     5876        g_renderer->deleteGraphicsObject<Group>(name);
     5877    } else {
     5878        g_renderer->deleteGraphicsObject<Group>("all");
     5879    }
     5880    return TCL_OK;
     5881}
     5882
     5883static int
     5884GroupOrientOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5885              Tcl_Obj *const *objv)
     5886{
     5887    double quat[4];
     5888    if (Tcl_GetDoubleFromObj(interp, objv[2], &quat[0]) != TCL_OK ||
     5889        Tcl_GetDoubleFromObj(interp, objv[3], &quat[1]) != TCL_OK ||
     5890        Tcl_GetDoubleFromObj(interp, objv[4], &quat[2]) != TCL_OK ||
     5891        Tcl_GetDoubleFromObj(interp, objv[5], &quat[3]) != TCL_OK) {
     5892        return TCL_ERROR;
     5893    }
     5894    if (objc == 7) {
     5895        const char *name = Tcl_GetString(objv[6]);
     5896        g_renderer->setGraphicsObjectOrientation<Group>(name, quat);
     5897    } else {
     5898        g_renderer->setGraphicsObjectOrientation<Group>("all", quat);
     5899    }
     5900    return TCL_OK;
     5901}
     5902
     5903static int
     5904GroupOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5905              Tcl_Obj *const *objv)
     5906{
     5907    double origin[3];
     5908    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     5909        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     5910        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     5911        return TCL_ERROR;
     5912    }
     5913    if (objc == 6) {
     5914        const char *name = Tcl_GetString(objv[5]);
     5915        g_renderer->setGraphicsObjectOrigin<Group>(name, origin);
     5916    } else {
     5917        g_renderer->setGraphicsObjectOrigin<Group>("all", origin);
     5918    }
     5919    return TCL_OK;
     5920}
     5921
     5922static int
     5923GroupPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5924                Tcl_Obj *const *objv)
     5925{
     5926    double pos[3];
     5927    if (Tcl_GetDoubleFromObj(interp, objv[2], &pos[0]) != TCL_OK ||
     5928        Tcl_GetDoubleFromObj(interp, objv[3], &pos[1]) != TCL_OK ||
     5929        Tcl_GetDoubleFromObj(interp, objv[4], &pos[2]) != TCL_OK) {
     5930        return TCL_ERROR;
     5931    }
     5932    if (objc == 6) {
     5933        const char *name = Tcl_GetString(objv[5]);
     5934        g_renderer->setGraphicsObjectPosition<Group>(name, pos);
     5935    } else {
     5936        g_renderer->setGraphicsObjectPosition<Group>("all", pos);
     5937    }
     5938    return TCL_OK;
     5939}
     5940
     5941static int
     5942GroupRemoveChildOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5943                   Tcl_Obj *const *objv)
     5944{
     5945    int numNodes;
     5946    Tcl_Obj **nodes = NULL;
     5947    if (Tcl_ListObjGetElements(interp, objv[2], &numNodes, &nodes) != TCL_OK) {
     5948        return TCL_ERROR;
     5949    }
     5950    std::vector<Group::NodeId> nodeList;
     5951    for (int i = 0; i < numNodes; i++) {
     5952        nodeList.push_back(Tcl_GetString(nodes[i]));
     5953    }
     5954    if (objc == 4) {
     5955        const char *name = Tcl_GetString(objv[3]);
     5956        g_renderer->removeChildrenFromGroup(name, nodeList);
     5957    } else {
     5958        g_renderer->removeChildrenFromGroup("all", nodeList);
     5959    }
     5960    return TCL_OK;
     5961}
     5962
     5963static int
     5964GroupScaleOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5965             Tcl_Obj *const *objv)
     5966{
     5967    double scale[3];
     5968    if (Tcl_GetDoubleFromObj(interp, objv[2], &scale[0]) != TCL_OK ||
     5969        Tcl_GetDoubleFromObj(interp, objv[3], &scale[1]) != TCL_OK ||
     5970        Tcl_GetDoubleFromObj(interp, objv[4], &scale[2]) != TCL_OK) {
     5971        return TCL_ERROR;
     5972    }
     5973    if (objc == 6) {
     5974        const char *name = Tcl_GetString(objv[5]);
     5975        g_renderer->setGraphicsObjectScale<Group>(name, scale);
     5976    } else {
     5977        g_renderer->setGraphicsObjectScale<Group>("all", scale);
     5978    }
     5979    return TCL_OK;
     5980}
     5981
     5982static int
     5983GroupVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
     5984               Tcl_Obj *const *objv)
     5985{
     5986    bool state;
     5987    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     5988        return TCL_ERROR;
     5989    }
     5990    if (objc == 4) {
     5991        const char *name = Tcl_GetString(objv[3]);
     5992        g_renderer->setGraphicsObjectVisibility<Group>(name, state);
     5993    } else {
     5994        g_renderer->setGraphicsObjectVisibility<Group>("all", state);
     5995    }
     5996    return TCL_OK;
     5997}
     5998
     5999static Rappture::CmdSpec groupOps[] = {
     6000    {"add",       1, GroupAddOp, 4, 4, "nodeList groupName"},
     6001    {"delete",    1, GroupDeleteOp, 2, 3, "?name?"},
     6002    {"orient",    4, GroupOrientOp, 6, 7, "qw qx qy qz ?name?"},
     6003    {"origin",    4, GroupOriginOp, 5, 6, "x y z ?name?"},
     6004    {"pos",       1, GroupPositionOp, 5, 6, "x y z ?name?"},
     6005    {"remove",    1, GroupRemoveChildOp, 3, 4, "nodeList ?name?"},
     6006    {"scale",     2, GroupScaleOp, 5, 6, "sx sy sz ?name?"},
     6007    {"visible",   1, GroupVisibleOp, 3, 4, "bool ?name?"},
     6008};
     6009static int nGroupOps = NumCmdSpecs(groupOps);
     6010
     6011static int
     6012GroupCmd(ClientData clientData, Tcl_Interp *interp, int objc,
     6013         Tcl_Obj *const *objv)
     6014{
     6015    Tcl_ObjCmdProc *proc;
     6016
     6017    proc = Rappture::GetOpFromObj(interp, nGroupOps, groupOps,
    54096018                                  Rappture::CMDSPEC_ARG1, objc, objv, 0);
    54106019    if (proc == NULL) {
     
    65537162
    65547163static int
     7164LineOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     7165             Tcl_Obj *const *objv)
     7166{
     7167    double origin[3];
     7168    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     7169        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     7170        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     7171        return TCL_ERROR;
     7172    }
     7173    if (objc == 6) {
     7174        const char *name = Tcl_GetString(objv[5]);
     7175        g_renderer->setGraphicsObjectOrigin<Line>(name, origin);
     7176    } else {
     7177        g_renderer->setGraphicsObjectOrigin<Line>("all", origin);
     7178    }
     7179    return TCL_OK;
     7180}
     7181
     7182static int
    65557183LinePositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    65567184               Tcl_Obj *const *objv)
     
    66147242    {"linewidth", 5, LineLineWidthOp, 3, 4, "width ?name?"},
    66157243    {"opacity",   2, LineOpacityOp, 3, 4, "value ?name?"},
    6616     {"orient",    2, LineOrientOp, 6, 7, "qw qx qy qz ?name?"},
     7244    {"orient",    4, LineOrientOp, 6, 7, "qw qx qy qz ?name?"},
     7245    {"origin",    4, LineOriginOp, 5, 6, "x y z ?name?"},
    66177246    {"pos",       2, LinePositionOp, 5, 6, "x y z ?name?"},
    66187247    {"scale",     2, LineScaleOp, 5, 6, "sx sy sz ?name?"},
     
    73928021
    73938022static int
    7394 PolyDataDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc,
    7395                  Tcl_Obj *const *objv)
    7396 {
    7397     if (objc == 3) {
    7398         const char *name = Tcl_GetString(objv[2]);
    7399         g_renderer->deleteGraphicsObject<PolyData>(name);
    7400     } else {
    7401         g_renderer->deleteGraphicsObject<PolyData>("all");
    7402     }
    7403     return TCL_OK;
    7404 }
    7405 
    7406 static int
    74078023PolyDataColorOp(ClientData clientData, Tcl_Interp *interp, int objc,
    74088024                Tcl_Obj *const *objv)
     
    74198035    } else {
    74208036        g_renderer->setGraphicsObjectColor<PolyData>("all", color);
     8037    }
     8038    return TCL_OK;
     8039}
     8040
     8041static int
     8042PolyDataCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8043                  Tcl_Obj *const *objv)
     8044{
     8045    bool state;
     8046    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     8047        return TCL_ERROR;
     8048    }
     8049    if (objc == 4) {
     8050        const char *name = Tcl_GetString(objv[3]);
     8051        g_renderer->setGraphicsObjectCulling<PolyData>(name, state);
     8052    } else {
     8053        g_renderer->setGraphicsObjectCulling<PolyData>("all", state);
     8054    }
     8055    return TCL_OK;
     8056}
     8057
     8058static int
     8059PolyDataDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8060                 Tcl_Obj *const *objv)
     8061{
     8062    if (objc == 3) {
     8063        const char *name = Tcl_GetString(objv[2]);
     8064        g_renderer->deleteGraphicsObject<PolyData>(name);
     8065    } else {
     8066        g_renderer->deleteGraphicsObject<PolyData>("all");
    74218067    }
    74228068    return TCL_OK;
     
    75568202
    75578203static int
     8204PolyDataOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8205                 Tcl_Obj *const *objv)
     8206{
     8207    double origin[3];
     8208    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     8209        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     8210        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     8211        return TCL_ERROR;
     8212    }
     8213    if (objc == 6) {
     8214        const char *name = Tcl_GetString(objv[5]);
     8215        g_renderer->setGraphicsObjectOrigin<PolyData>(name, origin);
     8216    } else {
     8217        g_renderer->setGraphicsObjectOrigin<PolyData>("all", origin);
     8218    }
     8219    return TCL_OK;
     8220}
     8221
     8222static int
    75588223PolyDataPointSizeOp(ClientData clientData, Tcl_Interp *interp, int objc,
    75598224                    Tcl_Obj *const *objv)
     
    76118276
    76128277static int
     8278PolyDataShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8279                  Tcl_Obj *const *objv)
     8280{
     8281    GraphicsObject::ShadingModel shadeModel;
     8282    const char *str = Tcl_GetString(objv[2]);
     8283    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     8284        shadeModel = GraphicsObject::SHADE_FLAT;
     8285    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     8286        shadeModel = GraphicsObject::SHADE_GOURAUD;
     8287    } else {
     8288         Tcl_AppendResult(interp, "bad shading option \"", str,
     8289                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     8290        return TCL_ERROR;
     8291    }
     8292    if (objc == 4) {
     8293        const char *name = Tcl_GetString(objv[3]);
     8294        g_renderer->setGraphicsObjectShadingModel<PolyData>(name, shadeModel);
     8295    } else {
     8296        g_renderer->setGraphicsObjectShadingModel<PolyData>("all", shadeModel);
     8297    }
     8298    return TCL_OK;
     8299}
     8300
     8301static int
    76138302PolyDataVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    76148303                  Tcl_Obj *const *objv)
     
    76488337    {"cloudstyle",2, PolyDataCloudStyleOp, 3, 4, "style ?dataSetName?"},
    76498338    {"color",     2, PolyDataColorOp, 5, 6, "r g b ?dataSetName?"},
     8339    {"culling",   2, PolyDataCullingOp, 3, 4, "bool ?name?"},
    76508340    {"delete",    1, PolyDataDeleteOp, 2, 3, "?dataSetName?"},
    76518341    {"edges",     1, PolyDataEdgeVisibilityOp, 3, 4, "bool ?dataSetName?"},
     
    76558345    {"material",  1, PolyDataMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?dataSetName?"},
    76568346    {"opacity",   2, PolyDataOpacityOp, 3, 4, "value ?dataSetName?"},
    7657     {"orient",    2, PolyDataOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"},
     8347    {"orient",    4, PolyDataOrientOp, 6, 7, "qw qx qy qz ?dataSetName?"},
     8348    {"origin",    4, PolyDataOriginOp, 5, 6, "x y z ?name?"},
    76588349    {"pos",       2, PolyDataPositionOp, 5, 6, "x y z ?dataSetName?"},
    76598350    {"ptsize",    2, PolyDataPointSizeOp, 3, 4, "size ?dataSetName?"},
    7660     {"scale",     1, PolyDataScaleOp, 5, 6, "sx sy sz ?dataSetName?"},
     8351    {"scale",     2, PolyDataScaleOp, 5, 6, "sx sy sz ?dataSetName?"},
     8352    {"shading",   2, PolyDataShadingOp, 3, 4, "val ?name?"},
    76618353    {"visible",   1, PolyDataVisibleOp, 3, 4, "bool ?dataSetName?"},
    76628354    {"wireframe", 1, PolyDataWireframeOp, 3, 4, "bool ?dataSetName?"}
     
    76838375{
    76848376    int numSides;
    7685     if (Tcl_GetIntFromObj(interp, objv[2], &numSides) != TCL_OK) {
    7686         return TCL_ERROR;
    7687     }
    7688     const char *name = Tcl_GetString(objv[3]);
    7689     if (!g_renderer->addPolygon(name, numSides)) {
     8377    double center[3], normal[3], radius;
     8378    if (Tcl_GetIntFromObj(interp, objv[2], &numSides) != TCL_OK ||
     8379        Tcl_GetDoubleFromObj(interp, objv[3], &center[0]) != TCL_OK ||
     8380        Tcl_GetDoubleFromObj(interp, objv[4], &center[1]) != TCL_OK ||
     8381        Tcl_GetDoubleFromObj(interp, objv[5], &center[2]) != TCL_OK ||
     8382        Tcl_GetDoubleFromObj(interp, objv[6], &normal[0]) != TCL_OK ||
     8383        Tcl_GetDoubleFromObj(interp, objv[7], &normal[1]) != TCL_OK ||
     8384        Tcl_GetDoubleFromObj(interp, objv[8], &normal[2]) != TCL_OK ||
     8385        Tcl_GetDoubleFromObj(interp, objv[9], &radius) != TCL_OK) {
     8386        return TCL_ERROR;
     8387    }
     8388    const char *name = Tcl_GetString(objv[10]);
     8389    if (!g_renderer->addPolygon(name, numSides, center, normal, radius)) {
    76908390        Tcl_AppendResult(interp, "Failed to create polygon", (char*)NULL);
    76918391        return TCL_ERROR;
     
    77278427
    77288428static int
     8429PolygonCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8430                 Tcl_Obj *const *objv)
     8431{
     8432    bool state;
     8433    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     8434        return TCL_ERROR;
     8435    }
     8436    if (objc == 4) {
     8437        const char *name = Tcl_GetString(objv[3]);
     8438        g_renderer->setGraphicsObjectCulling<Polygon>(name, state);
     8439    } else {
     8440        g_renderer->setGraphicsObjectCulling<Polygon>("all", state);
     8441    }
     8442    return TCL_OK;
     8443}
     8444
     8445static int
    77298446PolygonEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    77308447                        Tcl_Obj *const *objv)
     
    77398456    } else {
    77408457        g_renderer->setGraphicsObjectEdgeVisibility<Polygon>("all", state);
     8458    }
     8459    return TCL_OK;
     8460}
     8461
     8462static int
     8463PolygonFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8464                 Tcl_Obj *const *objv)
     8465{
     8466    bool state;
     8467    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     8468        return TCL_ERROR;
     8469    }
     8470    if (objc == 4) {
     8471        const char *name = Tcl_GetString(objv[3]);
     8472        g_renderer->setGraphicsObjectFlipNormals<Polygon>(name, state);
     8473    } else {
     8474        g_renderer->setGraphicsObjectFlipNormals<Polygon>("all", state);
    77418475    }
    77428476    return TCL_OK;
     
    78598593
    78608594static int
     8595PolygonOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8596                Tcl_Obj *const *objv)
     8597{
     8598    double origin[3];
     8599    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     8600        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     8601        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     8602        return TCL_ERROR;
     8603    }
     8604    if (objc == 6) {
     8605        const char *name = Tcl_GetString(objv[5]);
     8606        g_renderer->setGraphicsObjectOrigin<Polygon>(name, origin);
     8607    } else {
     8608        g_renderer->setGraphicsObjectOrigin<Polygon>("all", origin);
     8609    }
     8610    return TCL_OK;
     8611}
     8612
     8613static int
    78618614PolygonPositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    78628615                  Tcl_Obj *const *objv)
     
    78978650
    78988651static int
     8652PolygonShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     8653                 Tcl_Obj *const *objv)
     8654{
     8655    GraphicsObject::ShadingModel shadeModel;
     8656    const char *str = Tcl_GetString(objv[2]);
     8657    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     8658        shadeModel = GraphicsObject::SHADE_FLAT;
     8659    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     8660        shadeModel = GraphicsObject::SHADE_GOURAUD;
     8661    } else {
     8662         Tcl_AppendResult(interp, "bad shading option \"", str,
     8663                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     8664        return TCL_ERROR;
     8665    }
     8666    if (objc == 4) {
     8667        const char *name = Tcl_GetString(objv[3]);
     8668        g_renderer->setGraphicsObjectShadingModel<Polygon>(name, shadeModel);
     8669    } else {
     8670        g_renderer->setGraphicsObjectShadingModel<Polygon>("all", shadeModel);
     8671    }
     8672    return TCL_OK;
     8673}
     8674
     8675static int
    78998676PolygonVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    79008677                 Tcl_Obj *const *objv)
     
    79318708
    79328709static Rappture::CmdSpec polygonOps[] = {
    7933     {"add",       1, PolygonAddOp, 4, 4, "numSides name"},
     8710    {"add",       1, PolygonAddOp, 11, 11, "numSides centerX centerY centerZ normalX normalY normalZ radius name"},
    79348711    {"color",     1, PolygonColorOp, 5, 6, "r g b ?name?"},
     8712    {"culling",   2, PolygonCullingOp, 3, 4, "bool ?name?"},
    79358713    {"delete",    1, PolygonDeleteOp, 2, 3, "?name?"},
    79368714    {"edges",     1, PolygonEdgeVisibilityOp, 3, 4, "bool ?name?"},
     8715    {"flipnorms", 1, PolygonFlipNormalsOp, 3, 4, "bool ?name?"},
    79378716    {"lighting",  3, PolygonLightingOp, 3, 4, "bool ?name?"},
    79388717    {"linecolor", 5, PolygonLineColorOp, 5, 6, "r g b ?name?"},
     
    79408719    {"material",  1, PolygonMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    79418720    {"opacity",   2, PolygonOpacityOp, 3, 4, "value ?name?"},
    7942     {"orient",    2, PolygonOrientOp, 6, 7, "qw qx qy qz ?name?"},
     8721    {"orient",    4, PolygonOrientOp, 6, 7, "qw qx qy qz ?name?"},
     8722    {"origin",    4, PolygonOriginOp, 5, 6, "x y z ?name?"},
    79438723    {"pos",       2, PolygonPositionOp, 5, 6, "x y z ?name?"},
    7944     {"scale",     1, PolygonScaleOp, 5, 6, "sx sy sz ?name?"},
     8724    {"scale",     2, PolygonScaleOp, 5, 6, "sx sy sz ?name?"},
     8725    {"shading",   2, PolygonShadingOp, 3, 4, "val ?name?"},
    79458726    {"visible",   1, PolygonVisibleOp, 3, 4, "bool ?name?"},
    79468727    {"wireframe", 1, PolygonWireframeOp, 3, 4, "bool ?name?"}
     
    83829163
    83839164static int
     9165RendererLightsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     9166                 Tcl_Obj *const *objv)
     9167{
     9168    int idx;
     9169    bool state;
     9170    if (Tcl_GetIntFromObj(interp, objv[2], &idx) != TCL_OK) {
     9171        return TCL_ERROR;
     9172    }
     9173    if (GetBooleanFromObj(interp, objv[3], &state) != TCL_OK) {
     9174        return TCL_ERROR;
     9175    }
     9176    g_renderer->setLightSwitch(idx, state);
     9177    return TCL_OK;
     9178}
     9179
     9180static int
    83849181RendererTwoSidedLightingOp(ClientData clientData, Tcl_Interp *interp, int objc,
    83859182                           Tcl_Obj *const *objv)
     
    84049201    {"clipplane",  1, RendererClipPlaneOp, 5, 5, "axis ratio direction"},
    84059202    {"depthpeel",  1, RendererDepthPeelingOp, 3, 3, "bool"},
    8406     {"light2side", 1, RendererTwoSidedLightingOp, 3, 3, "bool"},
     9203    {"light2side", 6, RendererTwoSidedLightingOp, 3, 3, "bool"},
     9204    {"lights",     6, RendererLightsOp, 4, 4, "idx bool"},
    84079205    {"render",     1, RendererRenderOp, 2, 2, ""}
    84089206};
     
    84789276            Tcl_Obj *const *objv)
    84799277{
    8480     const char *name = Tcl_GetString(objv[2]);
    8481     if (!g_renderer->addGraphicsObject<Sphere>(name)) {
     9278    double center[3], radius;
     9279    if (Tcl_GetDoubleFromObj(interp, objv[2], &center[0]) != TCL_OK ||
     9280        Tcl_GetDoubleFromObj(interp, objv[3], &center[1]) != TCL_OK ||
     9281        Tcl_GetDoubleFromObj(interp, objv[4], &center[2]) != TCL_OK ||
     9282        Tcl_GetDoubleFromObj(interp, objv[5], &radius) != TCL_OK) {
     9283        return TCL_ERROR;
     9284    }
     9285    const char *name = Tcl_GetString(objv[6]);
     9286    if (!g_renderer->addSphere(name, center, radius)) {
    84829287        Tcl_AppendResult(interp, "Failed to create sphere", (char*)NULL);
    84839288        return TCL_ERROR;
     
    85199324
    85209325static int
     9326SphereCullingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     9327                Tcl_Obj *const *objv)
     9328{
     9329    bool state;
     9330    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     9331        return TCL_ERROR;
     9332    }
     9333    if (objc == 4) {
     9334        const char *name = Tcl_GetString(objv[3]);
     9335        g_renderer->setGraphicsObjectCulling<Sphere>(name, state);
     9336    } else {
     9337        g_renderer->setGraphicsObjectCulling<Sphere>("all", state);
     9338    }
     9339    return TCL_OK;
     9340}
     9341
     9342static int
    85219343SphereEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
    85229344                       Tcl_Obj *const *objv)
     
    85319353    } else {
    85329354        g_renderer->setGraphicsObjectEdgeVisibility<Sphere>("all", state);
     9355    }
     9356    return TCL_OK;
     9357}
     9358
     9359static int
     9360SphereFlipNormalsOp(ClientData clientData, Tcl_Interp *interp, int objc,
     9361                 Tcl_Obj *const *objv)
     9362{
     9363    bool state;
     9364    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     9365        return TCL_ERROR;
     9366    }
     9367    if (objc == 4) {
     9368        const char *name = Tcl_GetString(objv[3]);
     9369        g_renderer->setGraphicsObjectFlipNormals<Sphere>(name, state);
     9370    } else {
     9371        g_renderer->setGraphicsObjectFlipNormals<Sphere>("all", state);
    85339372    }
    85349373    return TCL_OK;
     
    86519490
    86529491static int
     9492SphereOriginOp(ClientData clientData, Tcl_Interp *interp, int objc,
     9493               Tcl_Obj *const *objv)
     9494{
     9495    double origin[3];
     9496    if (Tcl_GetDoubleFromObj(interp, objv[2], &origin[0]) != TCL_OK ||
     9497        Tcl_GetDoubleFromObj(interp, objv[3], &origin[1]) != TCL_OK ||
     9498        Tcl_GetDoubleFromObj(interp, objv[4], &origin[2]) != TCL_OK) {
     9499        return TCL_ERROR;
     9500    }
     9501    if (objc == 6) {
     9502        const char *name = Tcl_GetString(objv[5]);
     9503        g_renderer->setGraphicsObjectOrigin<Sphere>(name, origin);
     9504    } else {
     9505        g_renderer->setGraphicsObjectOrigin<Sphere>("all", origin);
     9506    }
     9507    return TCL_OK;
     9508}
     9509
     9510static int
    86539511SpherePositionOp(ClientData clientData, Tcl_Interp *interp, int objc,
    86549512                 Tcl_Obj *const *objv)
     
    87279585
    87289586static int
     9587SphereShadingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     9588                Tcl_Obj *const *objv)
     9589{
     9590    GraphicsObject::ShadingModel shadeModel;
     9591    const char *str = Tcl_GetString(objv[2]);
     9592    if (str[0] == 'f' && strcmp(str, "flat") == 0) {
     9593        shadeModel = GraphicsObject::SHADE_FLAT;
     9594    } else if (str[0] == 's' && strcmp(str, "smooth") == 0) {
     9595        shadeModel = GraphicsObject::SHADE_GOURAUD;
     9596    } else {
     9597         Tcl_AppendResult(interp, "bad shading option \"", str,
     9598                         "\": should be one of: 'flat', 'smooth'", (char*)NULL);
     9599        return TCL_ERROR;
     9600    }
     9601    if (objc == 4) {
     9602        const char *name = Tcl_GetString(objv[3]);
     9603        g_renderer->setGraphicsObjectShadingModel<Sphere>(name, shadeModel);
     9604    } else {
     9605        g_renderer->setGraphicsObjectShadingModel<Sphere>("all", shadeModel);
     9606    }
     9607    return TCL_OK;
     9608}
     9609
     9610static int
    87299611SphereVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    87309612                Tcl_Obj *const *objv)
     
    87619643
    87629644static Rappture::CmdSpec sphereOps[] = {
    8763     {"add",       1, SphereAddOp, 3, 3, "name"},
    8764     {"color",     1, SphereColorOp, 5, 6, "r g b ?name?"},
     9645    {"add",       1, SphereAddOp, 7, 7, "centerX centerY centerZ radius name"},
     9646    {"color",     2, SphereColorOp, 5, 6, "r g b ?name?"},
     9647    {"culling",   2, SphereCullingOp, 3, 4, "bool ?name?"},
    87659648    {"delete",    1, SphereDeleteOp, 2, 3, "?name?"},
    87669649    {"edges",     1, SphereEdgeVisibilityOp, 3, 4, "bool ?name?"},
     9650    {"flipnorms", 1, SphereFlipNormalsOp, 3, 4, "bool ?name?"},
    87679651    {"lighting",  3, SphereLightingOp, 3, 4, "bool ?name?"},
    87689652    {"linecolor", 5, SphereLineColorOp, 5, 6, "r g b ?name?"},
     
    87709654    {"material",  1, SphereMaterialOp, 6, 7, "ambientCoeff diffuseCoeff specularCoeff specularPower ?name?"},
    87719655    {"opacity",   2, SphereOpacityOp, 3, 4, "value ?name?"},
    8772     {"orient",    2, SphereOrientOp, 6, 7, "qw qx qy qz ?name?"},
     9656    {"orient",    4, SphereOrientOp, 6, 7, "qw qx qy qz ?name?"},
     9657    {"origin",    4, SphereOriginOp, 5, 6, "x y z ?name?"},
    87739658    {"pos",       2, SpherePositionOp, 5, 6, "x y z ?name?"},
    87749659    {"resolution",1, SphereResolutionOp, 4, 5, "thetaRes phiRes ?name?"},
    87759660    {"scale",     2, SphereScaleOp, 5, 6, "sx sy sz ?name?"},
    87769661    {"section",   2, SphereSectionOp, 6, 7, "thetaStart thetaEnd phiStart phiEnd ?name?"},
     9662    {"shading",   2, SphereShadingOp, 3, 4, "val ?name?"},
    87779663    {"visible",   1, SphereVisibleOp, 3, 4, "bool ?name?"},
    87789664    {"wireframe", 1, SphereWireframeOp, 3, 4, "bool ?name?"}
     
    1038911275    Tcl_CreateObjCommand(interp, "disk",        DiskCmd,        clientData, NULL);
    1039011276    Tcl_CreateObjCommand(interp, "glyphs",      GlyphsCmd,      clientData, NULL);
     11277    Tcl_CreateObjCommand(interp, "group",       GroupCmd,       clientData, NULL);
    1039111278    Tcl_CreateObjCommand(interp, "heightmap",   HeightMapCmd,   clientData, NULL);
    1039211279    Tcl_CreateObjCommand(interp, "imgflush",    ImageFlushCmd,  clientData, NULL);
     
    1042711314    Tcl_DeleteCommand(interp, "disk");
    1042811315    Tcl_DeleteCommand(interp, "glyphs");
     11316    Tcl_DeleteCommand(interp, "group");
    1042911317    Tcl_DeleteCommand(interp, "heightmap");
    1043011318    Tcl_DeleteCommand(interp, "imgflush");
  • trunk/packages/vizservers/vtkvis/RendererGraphicsObjs.cpp

    r3682 r3683  
    165165
    166166template <>
     167void Renderer::deleteGraphicsObject<Group>(const DataSetId& id)
     168{
     169    GroupHashmap& hashmap = getGraphicsObjectHashmap<Group>();
     170    GroupHashmap::iterator itr;
     171
     172    bool doAll = false;
     173
     174    if (id.compare("all") == 0) {
     175        itr = hashmap.begin();
     176        doAll = true;
     177    } else {
     178        itr = hashmap.find(id);
     179    }
     180    if (itr == hashmap.end()) {
     181        ERROR("Group not found: %s", id.c_str());
     182        return;
     183    }
     184
     185    TRACE("Deleting Group: %s", id.c_str());
     186
     187    do {
     188        Group *gobj = itr->second;
     189        if (gobj->getProp())
     190            _renderer->RemoveViewProp(gobj->getProp());
     191        if (gobj->getOverlayProp())
     192            _renderer->RemoveViewProp(gobj->getOverlayProp());
     193
     194        std::vector<GraphicsObject *> children;
     195        gobj->getChildren(children);
     196
     197        // Un-grouping children
     198        for (std::vector<GraphicsObject *>::iterator citr = children.begin();
     199             citr != children.end(); ++citr) {
     200            if ((*citr)->getProp())
     201                _renderer->AddViewProp((*citr)->getProp());
     202            if ((*citr)->getOverlayProp())
     203                _renderer->AddViewProp((*citr)->getOverlayProp());
     204        }
     205
     206        delete gobj;
     207
     208        itr = hashmap.erase(itr);
     209    } while (doAll && itr != hashmap.end());
     210
     211    sceneBoundsChanged();
     212    _needsRedraw = true;
     213}
     214
     215template <>
    167216bool Renderer::addGraphicsObject<Box>(const DataSetId& id)
    168217{
     
    262311using namespace VtkVis;
    263312
     313GraphicsObject *
     314Renderer::getGenericGraphicsObject(const DataSetId& id)
     315{
     316    GraphicsObject *gobj = NULL;
     317
     318    if ((gobj = getGraphicsObject<Arc>(id)) != NULL) {
     319        return gobj;
     320    }
     321    if ((gobj = getGraphicsObject<Arrow>(id)) != NULL) {
     322        return gobj;
     323    }
     324    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
     325        return gobj;
     326    }
     327    if ((gobj = getGraphicsObject<Cone>(id)) != NULL) {
     328        return gobj;
     329    }
     330    if ((gobj = getGraphicsObject<Cylinder>(id)) != NULL) {
     331        return gobj;
     332    }
     333    if ((gobj = getGraphicsObject<Disk>(id)) != NULL) {
     334        return gobj;
     335    }
     336    if ((gobj = getGraphicsObject<Line>(id)) != NULL) {
     337        return gobj;
     338    }
     339    if ((gobj = getGraphicsObject<Polygon>(id)) != NULL) {
     340        return gobj;
     341    }
     342    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
     343        return gobj;
     344    }
     345    //
     346    if ((gobj = getGraphicsObject<Contour2D>(id)) != NULL) {
     347        return gobj;
     348    }
     349    if ((gobj = getGraphicsObject<Contour3D>(id)) != NULL) {
     350        return gobj;
     351    }
     352    if ((gobj = getGraphicsObject<Cutplane>(id)) != NULL) {
     353        return gobj;
     354    }
     355    if ((gobj = getGraphicsObject<Glyphs>(id)) != NULL) {
     356        return gobj;
     357    }
     358    if ((gobj = getGraphicsObject<HeightMap>(id)) != NULL) {
     359        return gobj;
     360    }
     361    if ((gobj = getGraphicsObject<LIC>(id)) != NULL) {
     362        return gobj;
     363    }
     364    if ((gobj = getGraphicsObject<Molecule>(id)) != NULL) {
     365        return gobj;
     366    }
     367    if ((gobj = getGraphicsObject<Outline>(id)) != NULL) {
     368        return gobj;
     369    }
     370    if ((gobj = getGraphicsObject<PolyData>(id)) != NULL) {
     371        return gobj;
     372    }
     373    if ((gobj = getGraphicsObject<PseudoColor>(id)) != NULL) {
     374        return gobj;
     375    }
     376    if ((gobj = getGraphicsObject<Streamlines>(id)) != NULL) {
     377        return gobj;
     378    }
     379    if ((gobj = getGraphicsObject<Volume>(id)) != NULL) {
     380        return gobj;
     381    }
     382    if ((gobj = getGraphicsObject<Warp>(id)) != NULL) {
     383        return gobj;
     384    }
     385    //
     386    if ((gobj = getGraphicsObject<Group>(id)) != NULL) {
     387        return gobj;
     388    }
     389
     390    return NULL;
     391}
     392
    264393/**
    265394 * \brief Create a new Arc and associate it with an ID
    266395 */
    267 bool Renderer::addArc(const DataSetId& id, double pt1[3], double pt2[3])
     396bool Renderer::addArc(const DataSetId& id, double center[3],
     397                      double pt1[3], double pt2[3])
    268398{
    269399    Arc *gobj;
     
    288418    }
    289419
     420    gobj->setCenter(center);
    290421    gobj->setEndPoints(pt1, pt2);
    291422
     
    330461 * \brief Create a new Arrow and associate it with an ID
    331462 */
    332 bool Renderer::addArrow(const DataSetId& id, double tipRadius, double shaftRadius, double tipLength)
     463bool Renderer::addArrow(const DataSetId& id, double tipRadius,
     464                        double shaftRadius, double tipLength,
     465                        bool flipNormals)
    333466{
    334467    Arrow *gobj;
     
    355488    gobj->setRadii(tipRadius, shaftRadius);
    356489    gobj->setTipLength(tipLength);
     490    if (flipNormals)
     491        gobj->flipNormals(flipNormals);
    357492
    358493    getGraphicsObjectHashmap<Arrow>()[id] = gobj;
     
    394529
    395530/**
     531 * \brief Create a new Box and associate it with an ID
     532 */
     533bool Renderer::addBox(const DataSetId& id,
     534                      double xLen, double yLen, double zLen,
     535                      bool flipNormals)
     536{
     537    Box *gobj;
     538    if ((gobj = getGraphicsObject<Box>(id)) != NULL) {
     539        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
     540        deleteGraphicsObject<Box>(id);
     541    }
     542
     543    gobj = new Box();
     544 
     545    gobj->setDataSet(NULL, this);
     546
     547    if (gobj->getProp() == NULL &&
     548        gobj->getOverlayProp() == NULL) {
     549        delete gobj;
     550        return false;
     551    } else {
     552        if (gobj->getProp())
     553            _renderer->AddViewProp(gobj->getProp());
     554        if (gobj->getOverlayProp())
     555            _renderer->AddViewProp(gobj->getOverlayProp());
     556    }
     557
     558    gobj->setSize(xLen, yLen, zLen);
     559    if (flipNormals)
     560        gobj->flipNormals(flipNormals);
     561
     562    getGraphicsObjectHashmap<Box>()[id] = gobj;
     563
     564    sceneBoundsChanged();
     565    _needsRedraw = true;
     566    return true;
     567}
     568
     569/**
    396570 * \brief Create a new Cone and associate it with an ID
    397571 */
    398 bool Renderer::addCone(const DataSetId& id, double radius, double height, bool cap)
     572bool Renderer::addCone(const DataSetId& id, double radius, double height,
     573                       bool cap, bool flipNormals)
    399574{
    400575    Cone *gobj;
     
    422597    gobj->setHeight(height);
    423598    gobj->setCapping(cap);
     599    if (flipNormals)
     600        gobj->flipNormals(flipNormals);
    424601
    425602    getGraphicsObjectHashmap<Cone>()[id] = gobj;
     
    11001277 * \brief Create a new Cylinder and associate it with an ID
    11011278 */
    1102 bool Renderer::addCylinder(const DataSetId& id, double radius, double height, bool cap)
     1279bool Renderer::addCylinder(const DataSetId& id, double radius, double height,
     1280                           bool cap, bool flipNormals)
    11031281{
    11041282    Cylinder *gobj;
     
    11261304    gobj->setHeight(height);
    11271305    gobj->setCapping(cap);
     1306    if (flipNormals)
     1307        gobj->flipNormals(flipNormals);
    11281308
    11291309    getGraphicsObjectHashmap<Cylinder>()[id] = gobj;
     
    11351315
    11361316/**
    1137  * \brief Set Cylinder resolution
    1138  */
    1139 void Renderer::setCylinderResolution(const DataSetId& id, int res)
     1317 * \brief Set Cylinder capping
     1318 */
     1319void Renderer::setCylinderCapping(const DataSetId& id, bool state)
    11401320{
    11411321    CylinderHashmap::iterator itr;
     
    11571337
    11581338    do {
     1339        itr->second->setCapping(state);
     1340    } while (doAll && ++itr != _cylinders.end());
     1341
     1342    sceneBoundsChanged();
     1343    _needsRedraw = true;
     1344}
     1345
     1346/**
     1347 * \brief Set Cylinder resolution
     1348 */
     1349void Renderer::setCylinderResolution(const DataSetId& id, int res)
     1350{
     1351    CylinderHashmap::iterator itr;
     1352
     1353    bool doAll = false;
     1354
     1355    if (id.compare("all") == 0) {
     1356        itr = _cylinders.begin();
     1357        if (itr == _cylinders.end())
     1358            return;
     1359        doAll = true;
     1360    } else {
     1361        itr = _cylinders.find(id);
     1362    }
     1363    if (itr == _cylinders.end()) {
     1364        ERROR("Cylinder not found: %s", id.c_str());
     1365        return;
     1366    }
     1367
     1368    do {
    11591369        itr->second->setResolution(res);
    11601370    } while (doAll && ++itr != _cylinders.end());
     
    11671377 * \brief Create a new Disk and associate it with an ID
    11681378 */
    1169 bool Renderer::addDisk(const DataSetId& id, double innerRadius, double outerRadius)
     1379bool Renderer::addDisk(const DataSetId& id,
     1380                       double innerRadius,
     1381                       double outerRadius,
     1382                       bool flipNormals)
    11701383{
    11711384    Disk *gobj;
     
    11911404
    11921405    gobj->setRadii(innerRadius, outerRadius);
     1406    if (flipNormals)
     1407        gobj->flipNormals(flipNormals);
    11931408
    11941409    getGraphicsObjectHashmap<Disk>()[id] = gobj;
     
    14621677}
    14631678
     1679bool Renderer::addGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
     1680{
     1681    if (id.compare("all") == 0) {
     1682        addChildrenToGroup(id, nodeList);
     1683        return true;
     1684    }
     1685
     1686    Group *gobj;
     1687    if ((gobj = getGraphicsObject<Group>(id)) != NULL) {
     1688        // Group exists, so add nodes to it
     1689        addChildrenToGroup(id, nodeList);
     1690        return true;
     1691    }
     1692
     1693    gobj = new Group();
     1694 
     1695    gobj->setDataSet(NULL, this);
     1696
     1697    if (gobj->getProp() == NULL &&
     1698        gobj->getOverlayProp() == NULL) {
     1699        delete gobj;
     1700        return false;
     1701    } else {
     1702        if (gobj->getProp())
     1703            _renderer->AddViewProp(gobj->getProp());
     1704        if (gobj->getOverlayProp())
     1705            _renderer->AddViewProp(gobj->getOverlayProp());
     1706    }
     1707
     1708    for (std::vector<Group::NodeId>::const_iterator itr = nodeList.begin();
     1709         itr != nodeList.end(); ++itr) {
     1710        GraphicsObject *node = getGenericGraphicsObject(*itr);
     1711        if (node != NULL) {
     1712            if (node->getProp())
     1713                _renderer->RemoveViewProp(node->getProp());
     1714            if (node->getOverlayProp())
     1715                _renderer->RemoveViewProp(node->getOverlayProp());
     1716            gobj->addChild(*itr, node);
     1717        } else {
     1718            ERROR("Can't find node: %s", itr->c_str());
     1719        }
     1720    }
     1721
     1722    getGraphicsObjectHashmap<Group>()[id] = gobj;
     1723
     1724    sceneBoundsChanged();
     1725    _needsRedraw = true;
     1726    return true;
     1727}
     1728
     1729void Renderer::addChildrenToGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
     1730{
     1731    GroupHashmap::iterator itr;
     1732
     1733    bool doAll = false;
     1734
     1735    if (id.compare("all") == 0) {
     1736        itr = _groups.begin();
     1737        if (itr == _groups.end())
     1738            return;
     1739        doAll = true;
     1740    } else {
     1741        itr = _groups.find(id);
     1742    }
     1743
     1744    if (itr == _groups.end()) {
     1745        ERROR("Group not found: %s", id.c_str());
     1746        return;
     1747    }
     1748
     1749    do {
     1750        for (std::vector<Group::NodeId>::const_iterator citr = nodeList.begin();
     1751             citr != nodeList.end(); ++citr) {
     1752            GraphicsObject *node = getGenericGraphicsObject(*citr);
     1753            if (node != NULL) {
     1754                if (node->getProp())
     1755                    _renderer->RemoveViewProp(node->getProp());
     1756                if (node->getOverlayProp())
     1757                    _renderer->RemoveViewProp(node->getOverlayProp());
     1758                itr->second->addChild(*citr, node);
     1759            } else {
     1760                ERROR("Can't find node: %s", citr->c_str());
     1761            }
     1762        }
     1763     } while (doAll && ++itr != _groups.end());
     1764
     1765    sceneBoundsChanged();
     1766    _needsRedraw = true;
     1767}
     1768
     1769void Renderer::removeChildrenFromGroup(const DataSetId& id, const std::vector<Group::NodeId>& nodeList)
     1770{
     1771    GroupHashmap::iterator itr;
     1772
     1773    bool doAll = false;
     1774
     1775    if (id.compare("all") == 0) {
     1776        itr = _groups.begin();
     1777        if (itr == _groups.end())
     1778            return;
     1779        doAll = true;
     1780    } else {
     1781        itr = _groups.find(id);
     1782    }
     1783
     1784    if (itr == _groups.end()) {
     1785        ERROR("Group not found: %s", id.c_str());
     1786        return;
     1787    }
     1788
     1789    do {
     1790        for (std::vector<Group::NodeId>::const_iterator citr = nodeList.begin();
     1791             citr != nodeList.end(); ++citr) {
     1792            GraphicsObject *node = getGenericGraphicsObject(*citr);
     1793            if (node != NULL) {
     1794                if (node->getProp())
     1795                    _renderer->AddViewProp(node->getProp());
     1796                if (node->getOverlayProp())
     1797                    _renderer->AddViewProp(node->getOverlayProp());
     1798                assert(node == itr->second->removeChild(*citr));
     1799            } else {
     1800                ERROR("Can't find node: %s", citr->c_str());
     1801            }
     1802        }
     1803     } while (doAll && ++itr != _groups.end());
     1804
     1805    sceneBoundsChanged();
     1806    _needsRedraw = true;
     1807}
     1808
    14641809/**
    14651810 * \brief Create a new HeightMap and associate it with the named DataSet
     
    22862631 * \brief Create a new n-sided regular Polygon and associate it with an ID
    22872632 */
    2288 bool Renderer::addPolygon(const DataSetId& id, int numSides)
     2633bool Renderer::addPolygon(const DataSetId& id, int numSides,
     2634                          double center[3], double normal[3], double radius)
    22892635{
    22902636    Polygon *gobj;
     
    23102656
    23112657    gobj->setNumberOfSides(numSides);
     2658    gobj->setCenter(center);
     2659    gobj->setNormal(normal);
     2660    gobj->setRadius(radius);
    23122661
    23132662    getGraphicsObjectHashmap<Polygon>()[id] = gobj;
     
    24392788
    24402789    _needsRedraw = true;
     2790}
     2791
     2792/**
     2793 * \brief Create a new Sphere and associate it with an ID
     2794 */
     2795bool Renderer::addSphere(const DataSetId& id, double center[3], double radius, bool flipNormals)
     2796{
     2797    Sphere *gobj;
     2798    if ((gobj = getGraphicsObject<Sphere>(id)) != NULL) {
     2799        WARN("Replacing existing %s %s", gobj->getClassName(), id.c_str());
     2800        deleteGraphicsObject<Sphere>(id);
     2801    }
     2802
     2803    gobj = new Sphere();
     2804 
     2805    gobj->setDataSet(NULL, this);
     2806
     2807    if (gobj->getProp() == NULL &&
     2808        gobj->getOverlayProp() == NULL) {
     2809        delete gobj;
     2810        return false;
     2811    } else {
     2812        if (gobj->getProp())
     2813            _renderer->AddViewProp(gobj->getProp());
     2814        if (gobj->getOverlayProp())
     2815            _renderer->AddViewProp(gobj->getOverlayProp());
     2816    }
     2817
     2818    gobj->setCenter(center);
     2819    gobj->setRadius(radius);
     2820    if (flipNormals)
     2821        gobj->flipNormals(flipNormals);
     2822
     2823    getGraphicsObjectHashmap<Sphere>()[id] = gobj;
     2824
     2825    sceneBoundsChanged();
     2826    _needsRedraw = true;
     2827    return true;
    24412828}
    24422829
  • trunk/packages/vizservers/vtkvis/RendererGraphicsObjs.h

    r3621 r3683  
    277277
    278278/**
     279 * \brief Set the prop origin (center of rotation)
     280 */
     281template<class T>
     282void Renderer::setGraphicsObjectOrigin(const DataSetId& id, double origin[3])
     283{
     284    std::tr1::unordered_map<DataSetId, T *>& hashmap =
     285        getGraphicsObjectHashmap<T>();
     286    typename std::tr1::unordered_map<DataSetId, T *>::iterator itr;
     287
     288    bool doAll = false;
     289
     290    if (id.compare("all") == 0) {
     291        itr = hashmap.begin();
     292        if (itr == hashmap.end())
     293            return;
     294        doAll = true;
     295    } else {
     296        itr = hashmap.find(id);
     297    }
     298    if (itr == hashmap.end()) {
     299        GO_ERROR(T, "not found: %s", id.c_str());
     300        return;
     301    }
     302
     303    do {
     304        itr->second->setOrigin(origin);
     305    } while (doAll && ++itr != hashmap.end());
     306
     307    sceneBoundsChanged();
     308    _needsRedraw = true;
     309}
     310
     311/**
    279312 * \brief Set the prop position in world coords
    280313 */
     
    479512
    480513/**
     514 * \brief Set cull face for graphics object
     515 */
     516template<class T>
     517void Renderer::setGraphicsObjectCullFace(const DataSetId& id,
     518                                         GraphicsObject::CullFace state)
     519{
     520    std::tr1::unordered_map<DataSetId, T *>& hashmap =
     521        getGraphicsObjectHashmap<T>();
     522    typename std::tr1::unordered_map<DataSetId, T *>::iterator itr;
     523
     524    bool doAll = false;
     525
     526    if (id.compare("all") == 0) {
     527        itr = hashmap.begin();
     528        if (itr == hashmap.end())
     529            return;
     530        doAll = true;
     531    } else {
     532        itr = hashmap.find(id);
     533    }
     534
     535    if (itr == hashmap.end()) {
     536        GO_ERROR(T, "not found: %s", id.c_str());
     537        return;
     538    }
     539
     540    do {
     541        itr->second->setCullFace(state);
     542    } while (doAll && ++itr != hashmap.end());
     543
     544    _needsRedraw = true;
     545}
     546
     547/**
     548 * \brief Set face culling for graphics object
     549 */
     550template<class T>
     551void Renderer::setGraphicsObjectCulling(const DataSetId& id, bool state)
     552{
     553    std::tr1::unordered_map<DataSetId, T *>& hashmap =
     554        getGraphicsObjectHashmap<T>();
     555    typename std::tr1::unordered_map<DataSetId, T *>::iterator itr;
     556
     557    bool doAll = false;
     558
     559    if (id.compare("all") == 0) {
     560        itr = hashmap.begin();
     561        if (itr == hashmap.end())
     562            return;
     563        doAll = true;
     564    } else {
     565        itr = hashmap.find(id);
     566    }
     567
     568    if (itr == hashmap.end()) {
     569        GO_ERROR(T, "not found: %s", id.c_str());
     570        return;
     571    }
     572
     573    do {
     574        itr->second->setCulling(state);
     575    } while (doAll && ++itr != hashmap.end());
     576
     577    _needsRedraw = true;
     578}
     579
     580/**
    481581 * \brief Turn on/off edges for the given DataSet
    482582 */
     
    580680
    581681/**
     682 * \brief Flip normals and front/back faces of the shape geometry
     683 */
     684template<class T>
     685void Renderer::setGraphicsObjectFlipNormals(const DataSetId& id, bool state)
     686{
     687    std::tr1::unordered_map<DataSetId, T *>& hashmap =
     688        getGraphicsObjectHashmap<T>();
     689    typename std::tr1::unordered_map<DataSetId, T *>::iterator itr;
     690
     691    bool doAll = false;
     692
     693    if (id.compare("all") == 0) {
     694        itr = hashmap.begin();
     695        if (itr == hashmap.end())
     696            return;
     697        doAll = true;
     698    } else {
     699        itr = hashmap.find(id);
     700    }
     701    if (itr == hashmap.end()) {
     702        GO_ERROR(T, "not found: %s", id.c_str());
     703        return;
     704    }
     705
     706    do {
     707        itr->second->flipNormals(state);
     708    } while (doAll && ++itr != hashmap.end());
     709
     710    _needsRedraw = true;
     711}
     712
     713/**
    582714 * \brief Set ambient lighting/shading coefficient for the specified DataSet
    583715 */
     
    638770    do {
    639771        itr->second->setDiffuse(coeff);
     772    } while (doAll && ++itr != hashmap.end());
     773
     774    _needsRedraw = true;
     775}
     776
     777/**
     778 * \brief Set the shading of the object (flat or smooth)
     779 *
     780 * Currently Phong shading is not implemented
     781 */
     782template<class T>
     783void Renderer::setGraphicsObjectShadingModel(const DataSetId& id,
     784                                             GraphicsObject::ShadingModel state)
     785{
     786    std::tr1::unordered_map<DataSetId, T *>& hashmap =
     787        getGraphicsObjectHashmap<T>();
     788    typename std::tr1::unordered_map<DataSetId, T *>::iterator itr;
     789
     790    bool doAll = false;
     791
     792    if (id.compare("all") == 0) {
     793        itr = hashmap.begin();
     794        if (itr == hashmap.end())
     795            return;
     796        doAll = true;
     797    } else {
     798        itr = hashmap.find(id);
     799    }
     800    if (itr == hashmap.end()) {
     801        GO_ERROR(T, "not found: %s", id.c_str());
     802        return;
     803    }
     804
     805    do {
     806        itr->second->setShadingModel(state);
    640807    } while (doAll && ++itr != hashmap.end());
    641808
  • trunk/packages/vizservers/vtkvis/Sphere.cpp

    r3616 r3683  
    1515#include <vtkTransform.h>
    1616#include <vtkSphereSource.h>
     17#include <vtkReverseSense.h>
    1718
    1819#include "Sphere.h"
     
    5051    _pdMapper->Update();
    5152}
     53
     54void Sphere::flipNormals(bool state)
     55{
     56    if (_sphere == NULL || _pdMapper == NULL)
     57        return;
     58
     59    if (state) {
     60        vtkSmartPointer<vtkReverseSense> filter = vtkSmartPointer<vtkReverseSense>::New();
     61        filter->ReverseCellsOn();
     62        filter->ReverseNormalsOn();
     63        filter->SetInputConnection(_sphere->GetOutputPort());
     64
     65        _pdMapper->SetInputConnection(filter->GetOutputPort());
     66    } else {
     67        _pdMapper->SetInputConnection(_sphere->GetOutputPort());
     68    }
     69}
  • trunk/packages/vizservers/vtkvis/Sphere.h

    r3621 r3683  
    7777    }
    7878
     79    void setCenter(double center[3])
     80    {
     81        if (_sphere != NULL)
     82            _sphere->SetCenter(center);
     83    }
     84
    7985    void setRadius(double radius)
    8086    {
     
    8288            _sphere->SetRadius(radius);
    8389    }
     90
     91    void flipNormals(bool state);
    8492
    8593private:
  • trunk/packages/vizservers/vtkvis/protocol.txt

    r3682 r3683  
    248248         Toggle use of two-sided lighting (controls if backfaces are lit with a
    249249         flipped normal)
     250renderer lights <lightNum> <bool>
     251         Toggle lights on/off.  Light 0 is the headlight, light 1 the skylight
    250252renderer render
    251253         Force a new image to be rendered - use for advancing animation
     
    256258== Graphics objects ==
    257259
    258 arc add <pt1X> <pt1Y> <pt1Z> <pt2X> <pt2Y> <pt2Z> <name>
     260arc add <centerX> <centerY> <centerZ> <pt1X> <pt1Y> <pt1Z> <pt2X> <pt2Y> <pt2Z> <name>
    259261arc color <r> <g> <b> <?name?>
    260262arc delete <?name?>
     
    263265arc opacity <val> <?name?>
    264266arc orient <qw> <qx> <qy> <qz> <?name?>
     267arc origin <x> <y> <z> <?name?>
    265268arc pos <x> <y> <z> <?name?>
    266269arc resolution <res> <?name?>
     
    271274      Arrow will have base at 0,0,0 and tip at 1, 0, 0
    272275arrow color <r> <g> <b> <?name?>
     276arrow culling <bool> <?name?>
    273277arrow delete <?name?>
    274278arrow edges <bool> <?name?>
     279arrow flipnorm <bool> <?name?>
    275280arrow lighting <bool> <?name?>
    276281arrow linecolor <r> <g> <b> <?name?>
     
    279284arrow opacity <val> <?name?>
    280285arrow orient <qw> <qx> <qy> <qz> <?name?>
     286arrow origin <x> <y> <z> <?name?>
    281287arrow pos <x> <y> <z> <?name?>
    282288arrow resolution <tipRes> <shaftRes> <?name?>
    283289arrow scale <sx> <sy> <sz> <?name?>
     290arrow shading <val> <?name?>
     291      val = flat|smooth
    284292arrow visible <bool> <?name?>
    285293arrow wireframe <bool> <?name?>
    286294
    287 box add <name>
     295box add <xLen> <yLen> <zLen> <name>
    288296box color <r> <g> <b> <?name?>
     297box culling <bool> <?name?>
    289298box delete <?name?>
    290299box edges <bool> <?name?>
     300box flipnorm <bool> <?name?>
    291301box lighting <bool> <?name?>
    292302box linecolor <r> <g> <b> <?name?>
     
    295305box opacity <val> <?name?>
    296306box orient <qw> <qx> <qy> <qz> <?name?>
     307box origin <x> <y> <z> <?name?>
    297308box pos <x> <y> <z> <?name?>
    298309box scale <sx> <sy> <sz> <?name?>
     310box shading <val> <?name?>
     311    val = flat|smooth
    299312box visible <bool> <?name?>
    300313box wireframe <bool> <?name?>
     
    303316     <cap> = boolean flag for cap disks
    304317cone color <r> <g> <b> <?name?>
     318cone culling <bool> <?name?>
    305319cone delete <?name?>
    306320cone edges <bool> <?name?>
     321cone flipnorm <bool> <?name?>
    307322cone lighting <bool> <?name?>
    308323cone linecolor <r> <g> <b> <?name?>
     
    311326cone opacity <val> <?name?>
    312327cone orient <qw> <qx> <qy> <qz> <?name?>
     328cone origin <x> <y> <z> <?name?>
    313329cone pos <x> <y> <z> <?name?>
    314330cone resolution <res> <?name?>
    315331cone scale <sx> <sy> <sz> <?name?>
     332cone shading <val> <?name?>
     333     val = flat|smooth
    316334cone visible <bool> <?name?>
    317335cone wireframe <bool> <?name?>
     
    409427         <cap> = boolean flag for cap disks
    410428cylinder color <r> <g> <b> <?name?>
     429cylinder culling <bool> <?name?>
    411430cylinder delete <?name?>
    412431cylinder edges <bool> <?name?>
     432cylinder flipnorm <bool> <?name?>
    413433cylinder lighting <bool> <?name?>
    414434cylinder linecolor <r> <g> <b> <?name?>
     
    417437cylinder opacity <val> <?name?>
    418438cylinder orient <qw> <qx> <qy> <qz> <?name?>
     439cylinder origin <x> <y> <z> <?name?>
    419440cylinder pos <x> <y> <z> <?name?>
    420441cylinder resolution <res> <?name?>
    421442cylinder scale <sx> <sy> <sz> <?name?>
     443cylinder shading <val> <?name?>
     444         val = flat|smooth
    422445cylinder visible <bool> <?name?>
    423446cylinder wireframe <bool> <?name?>
     
    425448disk add <innerRadius> <outerRadius> <name>
    426449disk color <r> <g> <b> <?name?>
     450disk culling <bool> <?name?>
    427451disk delete <?name?>
    428452disk edges <bool> <?name?>
     453disk flipnorm <bool> <?name?>
    429454disk lighting <bool> <?name?>
    430455disk linecolor <r> <g> <b> <?name?>
     
    433458disk opacity <val> <?name?>
    434459disk orient <qw> <qx> <qy> <qz> <?name?>
     460disk origin <x> <y> <z> <?name?>
    435461disk pos <x> <y> <z> <?name?>
    436462disk resolution <resRadial> <resCircum> <?name?>
    437463disk scale <sx> <sy> <sz> <?name?>
     464disk shading <val> <?name?>
     465     val = flat|smooth
    438466disk visible <bool> <?name?>
    439467disk wireframe <bool> <?name?>
     
    471499glyphs visible <bool> <?datasetName?>
    472500glyphs wireframe <bool> <?datasetName?>
     501
     502group add <nodeList> <name>
     503group delete <?name?>
     504group orient <qw> <qx> <qy> <qz> <?name?>
     505group origin <x> <y> <z> <?name?>
     506group pos <x> <y> <z> <?name?>
     507group remove <nodeList> <name>
     508group scale <sx> <sy> <sz> <?name?>
     509group visible <bool> <?name?>
    473510
    474511heightmap add numcontours <n> <heightScale> <?dataSetName?>
     
    548585line opacity <val> <?name?>
    549586line orient <qw> <qx> <qy> <qz> <?name?>
     587line origin <x> <y> <z> <?name?>
    550588line pos <x> <y> <z> <?name?>
    551589line scale <sx> <sy> <sz> <?name?>
     
    610648         <style> = mesh | points
    611649polydata color <r> <g> <b> <?datasetName?>
     650polydata culling <bool> <?name?>
    612651polydata delete <?datasetName?>
    613652polydata edges <bool> <?datasetName?>
     
    618657polydata opacity <val> <?datasetName?>
    619658polydata orient <qw> <qx> <qy> <qz> <?dataSetName?>
     659polydata origin <x> <y> <z> <?name?>
    620660polydata pos <x> <y> <z> <?dataSetName?>
    621661polydata ptsize <size> <?dataSetName?>
    622662polydata scale <sx> <sy> <sz> <?dataSetName?>
     663polydata shading <val> <?name?>
     664         val = flat|smooth
    623665polydata visible <bool> <?datasetName?>
    624666polydata wireframe <bool> <?datasetName?>
    625667
    626 polygon add <numSides> <name>
     668polygon add <numSides> <centerX> <centerY> <centerZ> <normX> <normY> <normZ> <radius> <name>
    627669polygon color <r> <g> <b> <?name?>
     670polygon culling <bool> <?name?>
    628671polygon delete <?name?>
    629672polygon edges <bool> <?name?>
     673polygon flipnorm <bool> <?name?>
    630674polygon lighting <bool> <?name?>
    631675polygon linecolor <r> <g> <b> <?name?>
     
    634678polygon opacity <val> <?name?>
    635679polygon orient <qw> <qx> <qy> <qz> <?name?>
     680polygon origin <x> <y> <z> <?name?>
    636681polygon pos <x> <y> <z> <?name?>
    637682polygon scale <sx> <sy> <sz> <?name?>
     683polygon shading <val> <?name?>
     684        val = flat|smooth
    638685polygon visible <bool> <?name?>
    639686polygon wireframe <bool> <?name?>
     
    668715pseudocolor wireframe <bool> <?datasetName?>
    669716
    670 sphere add <name>
     717sphere add <centerX> <centerY> <centerZ> <radius> <name>
    671718sphere color <r> <g> <b> <?name?>
     719sphere culling <bool> <?name?>
    672720sphere delete <?name?>
    673721sphere edges <bool> <?name?>
     722sphere flipnorm <bool> <?name?>
    674723sphere lighting <bool> <?name?>
    675724sphere linecolor <r> <g> <b> <?name?>
     
    678727sphere opacity <val> <?name?>
    679728sphere orient <qw> <qx> <qy> <qz> <?name?>
     729sphere origin <x> <y> <z> <?name?>
    680730sphere pos <x> <y> <z> <?name?>
    681731sphere resolution <thetaRes> <phiRes> <?name?>
     
    683733sphere section <thetaStart> <thetaEnd> <phiStart> <phiEnd> <?name?>
    684734       Angles are in degrees
     735sphere shading <val> <?name?>
     736       val = flat|smooth
    685737sphere visible <bool> <?name?>
    686738sphere wireframe <bool> <?name?>
     
    785837warp pos <x> <y> <z> <?dataSetName?>
    786838warp preinterp <bool> <?dataSetName?>
    787      ontrols if VTK's InterpolateScalarsBeforeMapping option is set.
     839     Controls if VTK's InterpolateScalarsBeforeMapping option is set.
    788840     Setting this on will give more correct colors, as the interpolation
    789841     is done on texture coordinates that lookup into a 1D texture instead
Note: See TracChangeset for help on using the changeset viewer.