bool poly_write_normal_file(const GU_Detail *gdp, UT_String fname, const char * name, fpreal shutter, bool motionb, bool color, int subdiv_type, int subdiv_ite) { fpreal fps = OPgetDirector()->getChannelManager()->getSamplesPerSec(); GA_ROHandleV3 pos_h(gdp,GA_ATTRIB_POINT,"P"); UT_Vector3F pos_val(0,0,0); UT_Vector3F pprime_val(0,0,0); GA_ROHandleV3 uv_h(gdp,GA_ATTRIB_VERTEX,"uv"); UT_Vector3F uv_val(0,0,0); GA_ROHandleV3 n_h(gdp,GA_ATTRIB_VERTEX,"N"); UT_Vector3F n_val(0,0,0); GA_ROHandleV3 cd_h(gdp,GA_ATTRIB_POINT,"Cd"); UT_Vector3F cd_val(1,1,1); GA_ROHandleV3 v_h(gdp,GA_ATTRIB_POINT,"v"); UT_Vector3F v_val(0,0,0); int sample_count = motionb&&v_h.isValid()? 2:1; const GA_Primitive *prim; GA_Offset prim_off,lcl_start, lcl_end, ptoff; GA_Primitive::const_iterator vertex_it; UT_OFStream ass_file(fname); ass_file<<"polymesh\n{\n name "<<name; ass_file<<"\n nsides "<<gdp->getNumPrimitives()<<" 1 UINT\n"; for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim = gdp->getPrimitive(*p_it); ass_file<<prim->getVertexCount()<<" "; if((*p_it+1) % 300 == 0) ass_file<<"\n"; } ass_file<<"\n vidxs "<<gdp->getNumVertices()<<" 1 UINT\n"; //Reverse iteration for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); std::vector<int> idx; for(GA_Iterator v_it(prim->getVertexRange()); !v_it.atEnd(); ++v_it){ idx.push_back(gdp->pointIndex(gdp->vertexPoint(v_it.getOffset()))); } for(std::vector<int>::reverse_iterator r_it = idx.rbegin(); r_it!=idx.rend();++r_it) ass_file<<*r_it<<" "; idx.clear(); if((prim_off+1) % 300 == 0) ass_file<<"\n"; } ass_file<<"\n vlist "<<gdp->getNumPoints()<<" "<<sample_count<<" POINT\n"; for (GA_Iterator lcl_it((gdp)->getPointRange()); lcl_it.blockAdvance(lcl_start, lcl_end); ){ for (ptoff = lcl_start; ptoff < lcl_end; ++ptoff){ pos_val = pos_h.get(ptoff); ass_file<<pos_val.x()<<" "<<pos_val.y()<<" "<<pos_val.z()<<" "; if((ptoff+1) % 300 == 0) ass_file<<"\n"; } } if(motionb && v_h.isValid()){ for (GA_Iterator lcl_it((gdp)->getPointRange()); lcl_it.blockAdvance(lcl_start, lcl_end); ){ for (ptoff = lcl_start; ptoff < lcl_end; ++ptoff){ pos_val = pos_h.get(ptoff); if(v_h.isValid()) v_val = v_h.get(ptoff); pprime_val = pos_val + ((v_val / fps) * shutter); ass_file<<pprime_val.x()<<" "<<pprime_val.y()<<" "<<pprime_val.z()<<" "; if((ptoff+1) % 300 == 0) ass_file<<"\n"; } } } if(n_h.isValid()){ ass_file<<"\n nidxs "<<gdp->getNumVertices()<<" 1 UINT\n"; for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); for(GA_Iterator v_it(prim->getVertexRange()); !v_it.atEnd(); ++v_it){ ass_file<<gdp->vertexIndex(v_it.getOffset())<<" "; } if((prim_off+1) % 300 == 0) ass_file<<"\n"; } ass_file<<"\n nlist "<<gdp->getNumVertices()<<" "<<sample_count<<" VECTOR\n"; for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); std::vector<UT_Vector3F> nidx; for(prim->beginVertex(vertex_it); !vertex_it.atEnd(); ++vertex_it){ n_val = n_h(vertex_it.getVertexOffset()); nidx.push_back(n_val); } for(std::vector<UT_Vector3F>::reverse_iterator r_it = nidx.rbegin(); r_it!=nidx.rend();++r_it){ UT_Vector3F val = *r_it; ass_file<<val.x()<<" "<<val.y()<<" "<<val.z()<<" "; } nidx.clear(); if((prim_off+1) % 300 == 0) ass_file<<"\n"; } if(motionb){ for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); std::vector<UT_Vector3F> nidx; for(prim->beginVertex(vertex_it); !vertex_it.atEnd(); ++vertex_it){ n_val = n_h(vertex_it.getVertexOffset()); nidx.push_back(n_val); } for(std::vector<UT_Vector3F>::reverse_iterator r_it = nidx.rbegin(); r_it!=nidx.rend();++r_it){ UT_Vector3F val = *r_it; ass_file<<val.x()<<" "<<val.y()<<" "<<val.z()<<" "; } nidx.clear(); if((prim_off+1) % 300 == 0) ass_file<<"\n"; } } } if(uv_h.isValid()){ ass_file<<"\n uvidxs "<<gdp->getNumVertices()<<" 1 UINT\n"; for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); for(prim->beginVertex(vertex_it); !vertex_it.atEnd(); ++vertex_it){ ass_file<<gdp->vertexIndex(vertex_it.getVertexOffset())<<" "; } if((prim_off+1) % 300 == 0) ass_file<<"\n"; } ass_file<<"\n uvlist "<<gdp->getNumVertices()<<" 1 POINT2\n"; for(GA_Iterator p_it(gdp->getPrimitiveRange()); !p_it.atEnd();++p_it){ prim_off = p_it.getOffset(); prim = gdp->getPrimitive(prim_off); std::vector<UT_Vector3F> uvidx; for(prim->beginVertex(vertex_it); !vertex_it.atEnd(); ++vertex_it){ uv_val = uv_h(vertex_it.getVertexOffset()); uvidx.push_back(uv_val); } for(std::vector<UT_Vector3F>::reverse_iterator r_it = uvidx.rbegin(); r_it!=uvidx.rend();++r_it){ UT_Vector3F val = *r_it; ass_file<<val.x()<<" "<<val.y()<<" "; } uvidx.clear(); if((prim_off+1) % 300 == 0) ass_file<<"\n"; } } ass_file<<"\n smoothing on\n"; switch (subdiv_type) { case 0: // none break; case 1: // cat-clark ass_file<<" subdiv_type \"catclark\"\n"; break; case 2: // linear ass_file<<" subdiv_type \"linear\"\n"; break; } if(subdiv_ite>1) ass_file<<" subdiv_iterations "<<subdiv_ite<<"\n"; ass_file<<" visibility 255\n sidedness 255\n invert_normals off\n receive_shadows on\n self_shadows on\n" " opaque on\n matrix\n1 0 0 0\n0 1 0 0\n0 0 1 0\n0 0 0 1\n"; if(motionb) ass_file<<"1 0 0 0\n0 1 0 0\n0 0 1 0\n0 0 0 1\n"; ass_file<<"id 683108022"; if(color && cd_h.isValid()){ ass_file<<"\n declare Cd varying RGBA\n Cd "<<gdp->getNumPoints()<<" 1 RGBA\n"; for (GA_Iterator lcl_it((gdp)->getPointRange()); lcl_it.blockAdvance(lcl_start, lcl_end); ){ for (ptoff = lcl_start; ptoff < lcl_end; ++ptoff){ if(cd_h.isValid()) cd_val = cd_h.get(ptoff); ass_file<<cd_val.x()<<" "<<cd_val.y()<<" "<<cd_val.z()<<" "<<1<<" "; if((ptoff+1) % 300 == 0) ass_file<<"\n"; } } } ass_file<<"\n}"; ass_file.close(); return true; }
OP_ERROR aaOceanSOP::cookMySop(OP_Context &context) { if (lockInputs(context) >= UT_ERROR_ABORT) return error(); duplicateSource(0, context); setVariableOrder(3, 2, 0, 1); setCurGdh(0, myGdpHandle); setupLocalVars(); // variable declarations float now = context.getTime(); // Flag the SOP as being time dependent (i.e. cook on time changes) flags().timeDep = 1; // start pulling in SOP inputs and send to aaOcean enableEigens = (ENABLEEIGENS() != 0); if(pOcean->isChoppy() && enableEigens) enableEigens = TRUE; now = now + TIMEOFFSET(now); pOcean->input( RESOLUTION(), SEED(), OCEANSCALE(now), OCEANDEPTH(now), SURFACETENSION(now), VELOCITY(now), CUTOFF(now), WINDDIR(now), WINDALIGN(), DAMP(now), WAVESPEED(now), WAVEHEIGHT(now), CHOP(now), now, LOOPTIME(now), enableEigens, FALSE); // get the user-specified attribute that holds uv-data getUVAttributeName(UvAttribute); if(UvAttribute.length() == 0) UvAttribute = "uv"; const char* UVAttribName = (const char *)UvAttribute; uvRef = gdp->findFloatTuple(GA_ATTRIB_POINT, UVAttribName, 3); if(uvRef.isValid() == TRUE) { uvAttribute = uvRef.getAttribute(); uvTuple = uvRef.getAIFTuple(); } else { // uv attribute not found char msg[256]; sprintf(msg, "[aaOcean] Specified UV attribute \'%s\' not found on geometry.\ \nUV's are required for aaOcean to cook", UVAttribName); std::cout<<msg; std::cout.flush(); addError(SOP_MESSAGE, msg); unlockInputs(); return error(); } // setup local variables to output Eigens if(enableEigens) { eVecPlusRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecPlusName, 3); eVecMinusRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecMinusName, 3); eValuesRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eValuesName, 1); eVecPlusHandle = GA_RWHandleV3(eVecPlusRef.getAttribute()); eVecMinusHandle = GA_RWHandleV3(eVecMinusRef.getAttribute()); eValuesHandle = GA_RWHandleF(eValuesRef.getAttribute()); } // inputs validated. Begin writing ocean data to output handles int npts = gdp->getNumPoints(); #pragma omp parallel for for (int pt_offset = 0; pt_offset < npts; ++pt_offset) { UT_Vector3F pos = gdp->getPos3(pt_offset); UT_Vector3F UV; uvTuple->get(uvAttribute, pt_offset, UV.data(), 3); // Houdini V coord runs in opposite direction compared to Softimage/Maya // Conforming with other apps to make ocean shape consistent across apps float u = UV.x(); float v = 1.0f - (fmod(UV.y(), 1.0f)); pos.y() += pOcean->getOceanData(u, v, aaOcean::eHEIGHTFIELD); if(pOcean->isChoppy()) { pos.x() += pOcean->getOceanData(u, v, aaOcean::eCHOPX); pos.z() += pOcean->getOceanData(u, v, aaOcean::eCHOPZ); } gdp->setPos3(pt_offset, pos); if(enableEigens) { UT_Vector3F eigenVectorPlusValue; UT_Vector3F eigenVectorMinusValue; float eigenValue; eigenVectorPlusValue.x() = pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSX); eigenVectorPlusValue.y() = 0.0f; eigenVectorPlusValue.z() = pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSZ); eigenVectorMinusValue.x() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSX); eigenVectorMinusValue.y() = 0.0f; eigenVectorMinusValue.z() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSZ); eigenValue = pOcean->getOceanData(u, v, aaOcean::eFOAM); eVecPlusHandle.set(pt_offset,eigenVectorPlusValue); eVecMinusHandle.set(pt_offset,eigenVectorMinusValue); eValuesHandle.set(pt_offset,eigenValue); } } unlockInputs(); return error(); }