Imath::M44d HoudiniScene::readTransformAsMatrix( double time ) const { OP_Node *node = retrieveNode(); if ( node->isManager() ) { return Imath::M44d(); } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return Imath::M44d(); } // paths embedded within a sop always have identity transforms if ( m_contentIndex ) { return Imath::M44d(); } UT_DMatrix4 matrix; OP_Context context( time ); if ( !objNode->getLocalTransform( context, matrix ) ) { return Imath::M44d(); } return IECore::convert<Imath::M44d>( matrix ); }
ConstObjectPtr HoudiniScene::readObject( double time ) const { OBJ_Node *objNode = retrieveNode( true )->castToOBJNode(); if ( !objNode ) { return 0; } if ( objNode->getObjectType() == OBJ_GEOMETRY ) { OP_Context context( time ); GU_DetailHandle handle = objNode->getRenderGeometryHandle( context, false ); if ( !m_splitter || ( handle != m_splitter->handle() ) ) { m_splitter = new DetailSplitter( handle ); } GU_DetailHandle newHandle = m_splitter->split( contentPathValue() ); FromHoudiniGeometryConverterPtr converter = FromHoudiniGeometryConverter::create( ( newHandle.isNull() ) ? handle : newHandle ); if ( !converter ) { return 0; } return converter->convert(); } /// \todo: need to account for cameras and lights return 0; }
bool HoudiniScene::hasObject() const { OP_Node *node = retrieveNode( true ); if ( node->isManager() ) { return false; } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return false; } OBJ_OBJECT_TYPE type = objNode->getObjectType(); if ( type == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = objNode->getRenderGeometry( context, false ); // multiple named shapes define children that contain each object /// \todo: similar attribute logic is repeated in several places. unify in a single function if possible GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( !nameAttrRef.isValid() ) { return true; } const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); if ( !numShapes ) { return true; } for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match == *emptyString ) { // exact match return true; } } return false; } /// \todo: need to account for OBJ_CAMERA and OBJ_LIGHT return false; }
OP_Node *HoudiniScene::locateContent( OP_Node *node ) const { OBJ_Node *objNode = node->castToOBJNode(); if ( node->isManager() || ( objNode && objNode->getObjectType() == OBJ_SUBNET ) ) { for ( int i=0; i < node->getNchildren(); ++i ) { OP_Node *child = node->getChild( i ); if ( child->getName().equal( contentName.c_str() ) ) { return child; } } } else if ( objNode && objNode->getObjectType() == OBJ_GEOMETRY ) { return objNode; } return 0; }
Imath::M44d LiveScene::readWorldTransformAsMatrix( double time ) const { OP_Node *node = retrieveNode(); if ( node->isManager() ) { return Imath::M44d(); } OBJ_Node *objNode = node->castToOBJNode(); if ( !objNode ) { return Imath::M44d(); } UT_DMatrix4 matrix; OP_Context context( adjustTime( time ) ); if ( !objNode->getWorldTransform( matrix, context ) ) { return Imath::M44d(); } return IECore::convert<Imath::M44d>( matrix ); }
void OBJ_SceneCacheTransform::doExpandChildren( const SceneInterface *scene, OP_Network *parent, const Parameters ¶ms ) { UT_Interrupt *progress = UTgetInterrupt(); progress->setLongOpText( ( "Expanding " + scene->name().string() ).c_str() ); if ( progress->opInterrupt() ) { return; } OP_Network *inputNode = parent; if ( params.hierarchy == Parenting ) { parent = parent->getParent(); } SceneInterface::NameList children; scene->childNames( children ); for ( SceneInterface::NameList::const_iterator it=children.begin(); it != children.end(); ++it ) { ConstSceneInterfacePtr child = scene->child( *it ); OBJ_Node *childNode = 0; if ( params.hierarchy == SubNetworks ) { childNode = doExpandChild( child.get(), parent, params ); if ( params.depth == AllDescendants && child->hasObject() && tagged( child.get(), params.tagFilter ) ) { Parameters childParams( params ); childParams.depth = Children; doExpandObject( child.get(), childNode, childParams ); } } else if ( params.hierarchy == Parenting ) { if ( child->hasObject() ) { Parameters childParams( params ); childParams.depth = Children; childNode = doExpandObject( child.get(), parent, childParams ); } else { childNode = doExpandChild( child.get(), parent, params ); } childNode->setInput( 0, inputNode ); } if ( params.depth == AllDescendants ) { if ( params.hierarchy == SubNetworks && !tagged( child.get(), params.tagFilter ) ) { // we don't expand non-tagged children for SubNetwork mode, but we // do for Parenting mode, because otherwise the hierarchy would be // stuck in an un-expandable state. continue; } doExpandChildren( child.get(), childNode, params ); childNode->setInt( pExpanded.getToken(), 0, 0, 1 ); } } OP_Layout layout( parent ); #if UT_MAJOR_VERSION_INT >= 16 OP_SubnetIndirectInput *parentInput = parent->getParentInput( 0 ); layout.addLayoutItem( parentInput->getInputItem() ); for ( int i=0; i < parent->getNchildren(); ++i ) { layout.addLayoutItem( parent->getChild( i ) ); } #else layout.addLayoutOp( parent->getParentInput( 0 ) ); for ( int i=0; i < parent->getNchildren(); ++i ) { layout.addLayoutOp( parent->getChild( i ) ); } #endif layout.layoutOps( OP_LAYOUT_TOP_TO_BOT, parent, parent->getParentInput( 0 ) ); }
void OBJ_SceneCacheTransform::expandHierarchy( const SceneInterface *scene ) { if ( !scene ) { return; } Parameters params; params.geometryType = getGeometryType(); params.depth = (Depth)evalInt( pDepth.getToken(), 0, 0 ); params.hierarchy = (Hierarchy)evalInt( pHierarchy.getToken(), 0, 0 ); params.tagGroups = getTagGroups(); getAttributeFilter( params.attributeFilter ); getAttributeCopy( params.attributeCopy ); getShapeFilter( params.shapeFilter ); getTagFilter( params.tagFilterStr ); getTagFilter( params.tagFilter ); getFullPathName( params.fullPathName ); if ( params.hierarchy == FlatGeometry ) { // Collapse first, in case the immediate object was already created on during parent expansion collapseHierarchy(); doExpandObject( scene, this, params ); setInt( pExpanded.getToken(), 0, 0, 1 ); return; } OBJ_Node *rootNode = this; if ( scene->hasObject() ) { Parameters rootParams( params ); rootParams.hierarchy = SubNetworks; rootParams.depth = Children; OBJ_Node *objNode = doExpandObject( scene, this, rootParams ); if ( params.hierarchy == Parenting ) { rootNode = objNode; } } else if ( params.hierarchy == Parenting ) { /// \todo: this is terrible. can we use the subnet input instead? rootNode = reinterpret_cast<OBJ_Node*>( createNode( "geo", "TMP" ) ); } if ( params.hierarchy == Parenting ) { rootNode->setIndirectInput( 0, this->getParentInput( 0 ) ); } UT_Interrupt *progress = UTgetInterrupt(); if ( !progress->opStart( ( "Expand Hierarchy for " + getPath() ).c_str() ) ) { return; } doExpandChildren( scene, rootNode, params ); setInt( pExpanded.getToken(), 0, 0, 1 ); if ( params.hierarchy == Parenting && !scene->hasObject() ) { destroyNode( rootNode ); } progress->opEnd(); }
OP_Node *HoudiniScene::retrieveChild( const Name &name, Path &contentPath, MissingBehaviour missingBehaviour ) const { OP_Node *node = retrieveNode( false, missingBehaviour ); OP_Node *contentBaseNode = retrieveNode( true, missingBehaviour ); if ( !node || !contentBaseNode ) { return 0; } OBJ_Node *objNode = node->castToOBJNode(); OBJ_Node *contentNode = contentBaseNode->castToOBJNode(); // check subnet children if ( node->isManager() || ( objNode && objNode->getObjectType() == OBJ_SUBNET ) ) { for ( int i=0; i < node->getNchildren(); ++i ) { OP_Node *child = node->getChild( i ); // the contentNode is actually an extension of ourself if ( child == contentNode ) { continue; } if ( child->getName().equal( name.c_str() ) && !hasInput( child ) ) { return child; } } } if ( contentNode ) { // check connected outputs for ( unsigned i=0; i < contentNode->nOutputs(); ++i ) { OP_Node *child = contentNode->getOutput( i ); if ( child->getName().equal( name.c_str() ) ) { return child; } } // check child shapes within the geo if ( contentNode->getObjectType() == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = contentNode->getRenderGeometry( context, false ); GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( nameAttrRef.isValid() ) { const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match != *emptyString ) { std::pair<const char *, size_t> childMarker = nextWord( match ); std::string child( childMarker.first, childMarker.second ); if ( name == child ) { size_t contentSize = ( m_contentIndex ) ? m_path.size() - m_contentIndex : 0; if ( contentSize ) { contentPath.resize( contentSize ); std::copy( m_path.begin() + m_contentIndex, m_path.end(), contentPath.begin() ); } contentPath.push_back( name ); return contentNode; } } } } } } if ( missingBehaviour == SceneInterface::ThrowIfMissing ) { Path p; path( p ); std::string pStr; pathToString( p, pStr ); throw Exception( "IECoreHoudini::HoudiniScene::retrieveChild: Path \"" + pStr + "\" has no child named " + name.string() + "." ); } return 0; }
void HoudiniScene::childNames( NameList &childNames ) const { OP_Node *node = retrieveNode(); OBJ_Node *objNode = node->castToOBJNode(); OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode(); // add subnet children if ( node->isManager() || ( objNode && objNode->getObjectType() == OBJ_SUBNET ) ) { for ( int i=0; i < node->getNchildren(); ++i ) { OP_Node *child = node->getChild( i ); // ignore children that have incoming connections, as those are actually grandchildren // also ignore the contentNode, which is actually an extension of ourself if ( child != contentNode && !hasInput( child ) ) { childNames.push_back( Name( child->getName() ) ); } } } if ( !contentNode ) { return; } // add connected outputs for ( unsigned i=0; i < contentNode->nOutputs(); ++i ) { childNames.push_back( Name( contentNode->getOutput( i )->getName() ) ); } // add child shapes within the geometry if ( contentNode->getObjectType() == OBJ_GEOMETRY ) { OP_Context context( getDefaultTime() ); const GU_Detail *geo = contentNode->getRenderGeometry( context, false ); GA_ROAttributeRef nameAttrRef = geo->findStringTuple( GA_ATTRIB_PRIMITIVE, "name" ); if ( !nameAttrRef.isValid() ) { return; } const GA_Attribute *nameAttr = nameAttrRef.getAttribute(); const GA_AIFSharedStringTuple *tuple = nameAttr->getAIFSharedStringTuple(); GA_Size numShapes = tuple->getTableEntries( nameAttr ); for ( GA_Size i=0; i < numShapes; ++i ) { const char *currentName = tuple->getTableString( nameAttr, tuple->validateTableHandle( nameAttr, i ) ); const char *match = matchPath( currentName ); if ( match && *match != *emptyString ) { std::pair<const char *, size_t> childMarker = nextWord( match ); std::string child( childMarker.first, childMarker.second ); if ( std::find( childNames.begin(), childNames.end(), child ) == childNames.end() ) { childNames.push_back( child ); } } } } }
void HoudiniScene::readTags( NameList &tags, bool includeChildren ) const { tags.clear(); const OP_Node *node = retrieveNode(); if ( !node ) { return; } // add user supplied tags if we're not inside a SOP if ( !m_contentIndex && node->hasParm( pTags.getToken() ) ) { UT_String parmTagStr; node->evalString( parmTagStr, pTags.getToken(), 0, 0 ); if ( !parmTagStr.equal( UT_String::getEmptyString() ) ) { UT_WorkArgs tokens; parmTagStr.tokenize( tokens, " " ); for ( int i = 0; i < tokens.getArgc(); ++i ) { tags.push_back( tokens[i] ); } } } // add tags from the registered tag readers std::vector<CustomTagReader> &tagReaders = customTagReaders(); for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it ) { NameList values; it->m_read( node, values, includeChildren ); tags.insert( tags.end(), values.begin(), values.end() ); } // add tags based on primitive groups OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode(); if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter ) { GU_DetailHandle newHandle = m_splitter->split( contentPathValue() ); if ( !newHandle.isNull() ) { GU_DetailHandleAutoReadLock readHandle( newHandle ); if ( const GU_Detail *geo = readHandle.getGdp() ) { GA_Range prims = geo->getPrimitiveRange(); for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it ) { GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() ); if ( group->getInternal() || group->isEmpty() ) { continue; } const UT_String &groupName = group->getName(); if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) ) { UT_String tag; groupName.substr( tag, tagGroupPrefix.length() ); tag.substitute( "_", ":" ); tags.push_back( tag.buffer() ); } } } } } }
bool HoudiniScene::hasTag( const Name &name, bool includeChildren ) const { const OP_Node *node = retrieveNode(); if ( !node ) { return false; } // check for user supplied tags if we're not inside a SOP if ( !m_contentIndex && node->hasParm( pTags.getToken() ) ) { UT_String parmTags; node->evalString( parmTags, pTags.getToken(), 0, 0 ); if ( UT_String( name.c_str() ).multiMatch( parmTags ) ) { return true; } } // check with the registered tag readers std::vector<CustomTagReader> &tagReaders = customTagReaders(); for ( std::vector<CustomTagReader>::const_iterator it = tagReaders.begin(); it != tagReaders.end(); ++it ) { if ( it->m_has( node, name ) ) { return true; } } // check tags based on primitive groups OBJ_Node *contentNode = retrieveNode( true )->castToOBJNode(); if ( contentNode && contentNode->getObjectType() == OBJ_GEOMETRY && m_splitter ) { GU_DetailHandle newHandle = m_splitter->split( contentPathValue() ); if ( !newHandle.isNull() ) { GU_DetailHandleAutoReadLock readHandle( newHandle ); if ( const GU_Detail *geo = readHandle.getGdp() ) { GA_Range prims = geo->getPrimitiveRange(); for ( GA_GroupTable::iterator<GA_ElementGroup> it=geo->primitiveGroups().beginTraverse(); !it.atEnd(); ++it ) { GA_PrimitiveGroup *group = static_cast<GA_PrimitiveGroup*>( it.group() ); if ( group->getInternal() || group->isEmpty() ) { continue; } const UT_String &groupName = group->getName(); if ( groupName.startsWith( tagGroupPrefix ) && group->containsAny( prims ) ) { UT_String tag; groupName.substr( tag, tagGroupPrefix.length() ); tag.substitute( "_", ":" ); if ( tag.equal( name.c_str() ) ) { return true; } } } } } } return false; }
OP_ERROR SOP_Scallop::cookMySop(OP_Context &context) { //OP_Node::flags().timeDep = 1; bool clip = (lockInputs(context) < UT_ERROR_ABORT); UT_BoundingBox bbox; if(clip) { const GU_Detail* input = inputGeo(0,context); if(input != NULL) { //UT_Matrix4 bm; int res = input->getBBox(&bbox); if(res == 0) clip = false; } else clip = false; unlockInputs(); }; float now = context.getTime(); Daemon::now=now; Daemon::caller=this; Daemon::bias = evalFloat("bias",0,now); UT_Ramp ramp; float rampout[4]; bool useRamp = (evalInt("parmcolor",0,now)!=0); if(useRamp) { //PRM_Template *rampTemplate = PRMgetRampTemplate ("ramp", PRM_MULTITYPE_RAMP_RGB, NULL, NULL); if (ramp.getNodeCount () < 2) { ramp.addNode (0, UT_FRGBA (0, 0, 0, 1)); ramp.addNode (1, UT_FRGBA (1, 1, 1, 1)); }; updateRampFromMultiParm(now, getParm("ramp"), ramp); }; gdp->clearAndDestroy(); bool showPts = (evalInt("showpts",0,now)!=0); /* if(showPts) { float sz = evalInt("ptssz",0,now); if(sz > 0) { float one = 1.0f; gdp->addAttribute("showpoints",4,GA_ATTRIB_FLOAT_&one); gdp->addAttribute("revealsize",4,GB_ATTRIB_FLOAT,&sz); }; }; */ int cnt = evalInt("daemons", 0, now); Daemon* daemons=new Daemon[cnt]; float weights = 0; int totd=0; for(int i=1;i<=cnt;i++) { bool skip = (evalIntInst("enabled#",&i,0,now)==0); if(skip) continue; Daemon& d = daemons[totd]; UT_String path = ""; evalStringInst("obj#", &i, path, 0, now); if(path == "") continue; SOP_Node* node = getSOPNode(path); OBJ_Node* obj = dynamic_cast<OBJ_Node*>(node->getParent()); if(obj == NULL) continue; addExtraInput(obj, OP_INTEREST_DATA); //d.xform = obj->getWorldTransform(context); // 10.0 obj->getWorldTransform(d.xform, context); d.weight = evalFloatInst("weight#",&i,0,now); if(!useRamp) { d.c[0] = evalFloatInst("color#",&i,0,now); d.c[1] = evalFloatInst("color#",&i,1,now); d.c[2] = evalFloatInst("color#",&i,2,now); }; int mth = evalIntInst("model#",&i,0,now); switch(mth) { case 1: d.method = Methods::Spherical; break; case 2: d.method = Methods::Polar; break; case 3: d.method = Methods::Swirl; break; case 4: d.method = Methods::Trigonometric; break; case 5: { UT_String script; evalStringInst("vexcode#", &i, script, 0, now); d.SetupCVEX(script); if(d.useVex) { OP_Node* shop = (OP_Node*)findSHOPNode(script); addExtraInput(shop, OP_INTEREST_DATA); } break; } case 0: default: d.method = Methods::Linear; }; d.power = evalFloatInst("power#",&i,0,now); d.radius = evalFloatInst("radius#",&i,0,now); d.parameter = evalFloatInst("parameter#",&i,0,now); weights+=d.weight; totd++; }; if(totd == 0) { delete [] daemons; return error(); } float base = 0.0; for(int i=0;i<totd;i++) { Daemon& d = daemons[i]; d.range[0]=base; d.range[1] = base+d.weight/weights; base=d.range[1]; }; int total = evalInt("count",0,now); int degr = evalInt("degr",0,now); total >>= degr; GA_RWHandleI cntt(gdp->addIntTuple(GA_ATTRIB_POINT, "count", 4, GA_Defaults(1.0))); GB_AttributeRef dt(gdp->addDiffuseAttribute(GEO_POINT_DICT)); gdp->addVariableName("Cd","Cd"); UT_Vector3 current(0,0,0); float C[3] = { 0,0,0 }; float R=1.0f; bool trackRadii = (evalInt("trackradii",0,now)!=0); float rScale = evalFloat("radiiscale",0,now); GB_AttributeRef rt; if(trackRadii) { float one=1.0f; rt = gdp->addPointAttrib("width",4,GB_ATTRIB_FLOAT,&one); if(!GBisAttributeRefValid(rt)) trackRadii=false; else gdp->addVariableName("width","WIDTH"); }; float zero=0.0f; GB_AttributeRef pt = gdp->addPointAttrib("parameter",4,GB_ATTRIB_FLOAT,&zero); if(GBisAttributeRefValid(pt)) gdp->addVariableName("parameter","PARAMETER"); float param=0.0f; srand(0); UT_Interrupt* boss = UTgetInterrupt(); boss->opStart("Computing..."); for(int i=-50;i<total;i++) { bool ok = false; if (boss->opInterrupt()) break; float w = double(rand())/double(RAND_MAX); for(int j=0;j<totd;j++) { ok = daemons[j].Transform(w,current,C,R,param); if(ok) break; }; if(i<0) continue; if(clip) { if(!bbox.isInside(current)) continue; }; if(ok) { GEO_Point* p = gdp->appendPoint(); p->setPos(current); float* Cd=p->castAttribData<float>(dt); if(useRamp) { ramp.rampLookup(param,C); } memcpy(Cd,C,12); if(trackRadii) { float* _R = p->castAttribData<float>(rt); *_R=rScale*R; }; if(GBisAttributeRefValid(pt)) { float* _p = p->castAttribData<float>(pt); *_p=param; } }; }; boss->opEnd(); delete [] daemons; return error(); };
void SOP_Scallop::SaveData(float time) { OP_Context context(time); bool clip = (lockInputs(context) < UT_ERROR_ABORT); UT_BoundingBox bbox; if(clip) { const GU_Detail* input = inputGeo(0,context); if(input != NULL) { int res = input->getBBox(&bbox); if(res == 0) clip = false; } else clip = false; unlockInputs(); }; UT_String file; STR_PARM(file,"path", 8, 0, time); FILE* fp = fopen(file.buffer(),"wb"); if(fp == NULL) return; float& now=time; ////////////////////////////////////////////////////////////////////////// UT_Ramp ramp; float rampout[4]; bool useRamp = (evalInt("parmcolor",0,now)!=0); if(useRamp) { //PRM_Template *rampTemplate = PRMgetRampTemplate ("ramp", PRM_MULTITYPE_RAMP_RGB, NULL, NULL); if (ramp.getNodeCount () < 2) { ramp.addNode (0, UT_FRGBA (0, 0, 0, 1)); ramp.addNode (1, UT_FRGBA (1, 1, 1, 1)); }; updateRampFromMultiParm(now, getParm("ramp"), ramp); }; Daemon::now=now; Daemon::bias = evalFloat("bias",0,now); int cnt = evalInt("daemons", 0, now); Daemon* daemons=new Daemon[cnt]; float weights = 0; int totd=0; for(int i=1;i<=cnt;i++) { bool skip = (evalIntInst("enabled#",&i,0,now)==0); if(skip) continue; Daemon& d = daemons[totd]; UT_String path = ""; evalStringInst("obj#", &i, path, 0, now); if(path == "") continue; SOP_Node* node = getSOPNode(path); OBJ_Node* obj = dynamic_cast<OBJ_Node*>(node->getParent()); if(obj == NULL) continue; obj->getWorldTransform(d.xform,context); d.weight = evalFloatInst("weight#",&i,0,now); d.c[0] = evalFloatInst("color#",&i,0,now); d.c[1] = evalFloatInst("color#",&i,1,now); d.c[2] = evalFloatInst("color#",&i,2,now); int mth = evalIntInst("model#",&i,0,now); switch(mth) { case 1: d.method = Methods::Spherical; break; case 2: d.method = Methods::Polar; break; case 3: d.method = Methods::Swirl; break; case 4: d.method = Methods::Trigonometric; break; case 5: { UT_String script; evalStringInst("vexcode#", &i, script, 0, now); d.SetupCVEX(script); break; } case 0: default: d.method = Methods::Linear; }; d.power = evalFloatInst("power#",&i,0,now); d.radius = evalFloatInst("radius#",&i,0,now); d.parameter = evalFloatInst("parameter#",&i,0,now); weights+=d.weight; totd++; }; if(totd == 0) { delete [] daemons; return; } float base = 0.0; for(int i=0;i<totd;i++) { Daemon& d = daemons[i]; d.range[0]=base; d.range[1] = base+d.weight/weights; base=d.range[1]; }; int total = evalInt("count",0,now); //fwrite(&total,sizeof(int),1,fp); UT_Vector3 current(0,0,0); float* C = data; float R=1.0f; float rScale = evalFloat("radiiscale",0,now); float param=0.0f; srand(0); for(int i=-50;i<total;i++) { bool ok = false; float w = double(rand())/double(RAND_MAX); for(int j=0;j<totd;j++) { ok = daemons[j].Transform(w,current,C,R,*G); if(ok) break; }; if(i<0) continue; if(clip) { if(!bbox.isInside(current)) continue; }; if(ok) { if(useRamp) { float out[4]; ramp.rampLookup(data[3],out); memcpy(data,out,12); } fwrite(current.vec,12,1,fp); // P float r = R*rScale; fwrite(&r,4,1,fp); // R fwrite(data,16,1,fp); // Cs+p }; }; delete [] daemons; ////////////////////////////////////////////////////////////////////////// fclose(fp); };
void SOP_Scallop::SaveDivMap(float time) { OP_Context context(time); bool clip = (lockInputs(context) < UT_ERROR_ABORT); UT_BoundingBox bbox; if(clip) { const GU_Detail* input = inputGeo(0,context); if(input != NULL) { //UT_Matrix4 bm; int res = input->getBBox(&bbox); if(res == 0) clip = false; } else clip = false; unlockInputs(); }; if(!clip) return; UT_String file; STR_PARM(file,"mappath", 11, 0, time); float& now=time; ////////////////////////////////////////////////////////////////////////// Daemon::now=now; Daemon::bias = evalFloat("bias",0,now); int cnt = evalInt("daemons", 0, now); Daemon* daemons=new Daemon[cnt]; float weights = 0; int totd=0; float maxR = 0; for(int i=1;i<=cnt;i++) { bool skip = (evalIntInst("enabled#",&i,0,now)==0); if(skip) continue; Daemon& d = daemons[totd]; UT_String path = ""; evalStringInst("obj#", &i, path, 0, now); if(path == "") continue; SOP_Node* node = getSOPNode(path); OBJ_Node* obj = dynamic_cast<OBJ_Node*>(node->getParent()); if(obj == NULL) continue; obj->getWorldTransform(d.xform,context); d.weight = evalFloatInst("weight#",&i,0,now); d.c[0] = evalFloatInst("color#",&i,0,now); d.c[1] = evalFloatInst("color#",&i,1,now); d.c[2] = evalFloatInst("color#",&i,2,now); int mth = evalIntInst("model#",&i,0,now); switch(mth) { case 1: d.method = Methods::Spherical; break; case 2: d.method = Methods::Polar; break; case 3: d.method = Methods::Swirl; break; case 4: d.method = Methods::Trigonometric; break; case 5: { UT_String script; evalStringInst("vexcode#", &i, script, 0, now); d.SetupCVEX(script); break; }; case 0: default: d.method = Methods::Linear; }; d.power = evalFloatInst("power#",&i,0,now); d.radius = evalFloatInst("radius#",&i,0,now); d.parameter = evalFloatInst("parameter#",&i,0,now); if(d.radius > maxR) maxR = d.radius; weights+=d.weight; totd++; }; if(totd == 0) { delete [] daemons; return; }; float base = 0.0; for(int i=0;i<totd;i++) { Daemon& d = daemons[i]; d.range[0]=base; d.range[1] = base+d.weight/weights; base=d.range[1]; }; ////////////////////////////////////////////////////////////////////////// int total = evalInt("count",0,now); int degr = evalInt("degr",0,now); total >>= degr; GU_Detail det; UT_Vector3 current(0,0,0); float C[3] = { 0,0,0 }; float R=1.0f; float param=0.0f; srand(0); bool medial = (evalInt("mapmedial",0,now)!=0); int mapdiv = evalInt("mapdiv",0,now); //BoundBox Box; OctreeBox O(mapdiv); //if(medial) //{ O.bbox=bbox; //} //else //{ // BoundBox::limit = evalInt("nodecount", 0, now); // BoundBox::medial = (evalInt("mapmedial",0,now)!=0); // float boxb[6]; // memcpy(boxb,bbox.minvec().vec,12); // memcpy(boxb+3,bbox.maxvec().vec,12); // Box.Organize(boxb); //}; for(int i=-50;i<total;i++) { bool ok = false; float w = double(rand())/double(RAND_MAX); for(int j=0;j<totd;j++) { ok = daemons[j].Transform(w,current,C,R,param); if(ok) break; }; if(i<0) continue; //if(medial) //{ float P[4] = { current.x(), current.y(), current.z(), R }; O.Insert(P); //} //else //{ // Box.CheckPoint(current.vec); //} }; delete [] daemons; ////////////////////////////////////////////////////////////////////////// int ita[3] = {-1,-1,-1}; //if(medial) //{ int count = 0; OctreeBox::at = det.addPrimAttrib("count",4,GB_ATTRIB_INT,&count); det.addVariableName("count","COUNT"); float radius = 0.0f; OctreeBox::rt = det.addAttrib("radius",4,GB_ATTRIB_FLOAT,&radius); det.addVariableName("radius","RADIUS"); OctreeBox::it = det.addPrimAttrib("mask",12,GB_ATTRIB_INT,ita); det.addVariableName("mask","MASK"); float box[6] = {bbox.xmin(),bbox.xmax(),bbox.ymin(),bbox.ymax(),bbox.zmin(),bbox.zmax()}; det.addAttrib("bbox",24,GB_ATTRIB_FLOAT,box); O.maxlevel = 0x01<<mapdiv; O.parentbbox = bbox; O.Build(det); //} //else Box.Build(det); det.save(file.buffer(),1,NULL); // ...SAVE ATLAS { UT_String atlas =file; atlas+=".atlas"; FILE* fa = fopen(atlas.buffer(),"wb"); GEO_PrimList& pl = det.primitives(); int cnt = pl.entries(); fwrite(&cnt,sizeof(int),1,fa); float bb[6] = { bbox.xmin(), bbox.xmax(), bbox.ymin(), bbox.ymax(), bbox.zmin(), bbox.zmax() }; fwrite(bb,sizeof(float),6,fa); fwrite(&(O.maxlevel),sizeof(int),1,fa); fwrite(&(O.maxlevel),sizeof(int),1,fa); fwrite(&(O.maxlevel),sizeof(int),1,fa); for(int i=0;i<cnt;i++) { const GEO_PrimVolume* v = dynamic_cast<const GEO_PrimVolume*>(pl[i]); UT_BoundingBox b; v->getBBox(&b); float _bb[6] = { b.xmin(), b.xmax(), b.ymin(), b.ymax(), b.zmin(), b.zmax() }; fwrite(_bb,sizeof(float),6,fa); // MASK fwrite(v->castAttribData<int>(OctreeBox::it),sizeof(int),3,fa); } fclose(fa); } };