00001 /* 00002 * Copyright (c) 2012 00003 * Side Effects Software Inc. All rights reserved. 00004 * 00005 * Redistribution and use of Houdini Development Kit samples in source and 00006 * binary forms, with or without modification, are permitted provided that the 00007 * following conditions are met: 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 2. The name of Side Effects Software may not be used to endorse or 00011 * promote products derived from this software without specific prior 00012 * written permission. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS 00015 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00017 * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00019 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00020 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00021 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00022 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00023 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 * 00025 *---------------------------------------------------------------------------- 00026 * 00027 * This class implements an object that aligns the inherited orientation to the 00028 * world axes while preserving the location in space. It also illustrates how to 00029 * hide all the parameters inherited from the base class. 00030 * 00031 */ 00032 00033 #include "OBJ_WorldAlign.h" 00034 #include <UT/UT_DSOVersion.h> 00035 #include <UT/UT_DMatrix3.h> 00036 #include <OP/OP_OperatorTable.h> 00037 00038 00039 using namespace HDK_Sample; 00040 00041 00042 00043 // Constructor for new object class 00044 OBJ_WorldAlign::OBJ_WorldAlign( OP_Network *net, 00045 const char *name, OP_Operator *op ) 00046 : OBJ_Geometry(net, name, op) 00047 { 00048 // initialize local member data here. 00049 } 00050 00051 00052 00053 // virtual destructor for new object class 00054 OBJ_WorldAlign::~OBJ_WorldAlign() 00055 { 00056 } 00057 00058 00059 00060 // this is the template list that defines the new parameters that are 00061 // used by the worldalign object. In this particular case the list is empty 00062 // because we have no new parameters. 00063 static PRM_Template templatelist[] = 00064 { 00065 // blank terminating Template. 00066 PRM_Template() 00067 }; 00068 00069 00070 00071 // this function copies the original parameter and then adds an invisible flag 00072 static void 00073 copyParmWithInvisible(PRM_Template &src, PRM_Template &dest) 00074 { 00075 PRM_Name * new_name; 00076 00077 new_name = new PRM_Name(src.getToken(), src.getLabel(), 00078 src.getExpressionFlag()); 00079 new_name->harden(); 00080 dest.initialize( 00081 (PRM_Type) (src.getType() | PRM_TYPE_INVISIBLE), 00082 src.getTypeExtended(), 00083 src.exportLevel(), 00084 src.getVectorSize(), 00085 new_name, 00086 src.getFactoryDefaults(), 00087 src.getChoiceListPtr(), 00088 src.getRangePtr(), 00089 src.getCallback(), 00090 src.getSparePtr(), 00091 src.getParmGroup(), 00092 (const char *)src.getHelpText(), 00093 src.getDisablePtr()); 00094 } 00095 00096 00097 00098 // this function returns the OP_TemplatePair that combines the parameters 00099 // of this object with those of its ancestors in the (object class hierarchy) 00100 OP_TemplatePair * 00101 OBJ_WorldAlign::buildTemplatePair(OP_TemplatePair *prevstuff) 00102 { 00103 OP_TemplatePair *align, *geo; 00104 00105 // The parm templates here are not created as a static list because 00106 // if that static list was built before the OBJbaseTemplate static list 00107 // (which it references) then that list would be corrupt. Thus we have 00108 // to force our static list to be created after OBJbaseTemplate. 00109 static PRM_Template *theTemplate = 0; 00110 00111 if(!theTemplate) 00112 { 00113 PRM_Template *obj_template; 00114 int i; 00115 int size; 00116 UT_String parm_name; 00117 00118 obj_template = OBJ_Geometry::getTemplateList(OBJ_PARMS_PLAIN); 00119 size = PRM_Template::countTemplates( obj_template ); 00120 theTemplate = new PRM_Template[size + 1]; // add +1 for sentinel 00121 for( i = 0; i < size; i++ ) 00122 { 00123 theTemplate[i] = obj_template[i]; 00124 theTemplate[i].getToken( parm_name ); 00125 00126 // leave only the translation parameter visible (and its containing 00127 // switcher) 00128 if( parm_name != "t" && parm_name != "stdswitcher" ) 00129 copyParmWithInvisible( obj_template[i], theTemplate[i] ); 00130 } 00131 } 00132 00133 // Here, we have to "inherit" template pairs from geometry and beyond. To 00134 // do this, we first need to instantiate our template list, then add the 00135 // base class templates. 00136 align = new OP_TemplatePair(templatelist, prevstuff); 00137 geo = new OP_TemplatePair(theTemplate, align); 00138 00139 return geo; 00140 } 00141 00142 00143 00144 // the myConstructor method is used to create new objects of the correct 00145 // type from the OperatorTable. This method is passed to the OP_Operator 00146 // constructor and then is invoked whenever a new node needs to be created. 00147 OP_Node * 00148 OBJ_WorldAlign::myConstructor(OP_Network *net, const char *name, OP_Operator *op) 00149 { 00150 return new OBJ_WorldAlign(net, name, op); 00151 } 00152 00153 00154 00155 OP_ERROR 00156 OBJ_WorldAlign::cookMyObj(OP_Context &context) 00157 { 00158 OP_ERROR errorstatus; 00159 UT_DMatrix3 rotation; 00160 UT_DMatrix4 rotation4; 00161 00162 // OBJ_Geometry::cookMyObj computes the local and global transform, and 00163 // dirties the inverse of the global transform matrix. These are stored 00164 // in myXform, myWorldXform, and myIWorldXform, respectively. 00165 errorstatus = OBJ_Geometry::cookMyObj(context); 00166 00167 // get rid of the rotation component in the matrices 00168 myWorldXform.extractRotate(rotation); 00169 if( ! rotation.invert() ) 00170 { 00171 rotation4 = rotation; 00172 myWorldXform = rotation4 * myWorldXform; 00173 myXform = rotation4 * myXform; 00174 } 00175 00176 return errorstatus; 00177 } 00178 00179 00180 00181 // this function installs the new object in houdini's object table. 00182 // It is automatically called by Houdini when this dynamic library is loaded. 00183 void 00184 newObjectOperator(OP_OperatorTable *table) 00185 { 00186 table->addOperator(new OP_Operator( 00187 "hdk_worldalign", // operator unique name 00188 "World Align", // operator label 00189 OBJ_WorldAlign::myConstructor, // node instance constructor 00190 OBJ_WorldAlign::buildTemplatePair(0), // parameters 00191 0, // minimum inputs 00192 1, // maximum inputs 00193 0)); // variables 00194 }
1.5.9