OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context )
{
	flags().setTimeDep( true );
	
	std::string file;
	if ( !ensureFile( file ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	std::string path = getPath();
	Space space = getSpace();
	
	UT_String shapeFilterStr;
	evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 );
	UT_StringMMPattern shapeFilter;
	shapeFilter.compile( shapeFilterStr );
	
	UT_String p( "P" );
	UT_String attributeFilter;
	evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 );
	if ( !p.match( attributeFilter ) )
	{
		attributeFilter += " P";
	}
	
	ConstSceneInterfacePtr scene = this->scene( file, path );
	if ( !scene )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	MurmurHash hash;
	hash.append( file );
	hash.append( path );
	hash.append( space );
	hash.append( shapeFilterStr );
	hash.append( attributeFilter );
	
	if ( !m_loaded || m_hash != hash )
	{
		gdp->clearAndDestroy();
	}
	
	Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d();
	
	SceneInterface::Path rootPath;
	scene->path( rootPath );
	
	loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), rootPath.size() );
	
	m_loaded = true;
	m_hash = hash;
	
	return error();
}
Пример #2
0
OP_ERROR
GusdOBJ_usdcamera::_Cook(OP_Context& ctx)
{
    _LoadCamera(ctx.getTime(), ctx.getThread());
    
    /* XXX: There's a potential race condition here, between
            loading and stealing cached errors.
            Would be better to keep the camera cache locked
            until the error stealing is done.*/
    
    UT_AutoReadLock readLock(_lock);
    stealErrors(_errors, /*borrow*/ true);
    return error();
}
Пример #3
0
OP_ERROR
GusdSOP_usdimport::_Cook(OP_Context& ctx)
{
    fpreal t = ctx.getTime();

    UT_String traversal;
    evalString( traversal, "import_traversal", 0, t );

    ErrorChoice errorMode = static_cast<ErrorChoice>(evalInt("missingframe", 0, t ));

    auto lockedMgr = getLockedErrorManager();
    GusdUT_ErrorManager errMgr(*lockedMgr);
    GusdUT_ErrorContext errContext(errMgr, 
        errorMode == MISSINGFRAME_WARN ? UT_ERROR_WARNING : UT_ERROR_ABORT);

    const GusdUSD_Traverse* trav = NULL;
    if(traversal != _NOTRAVERSE_NAME) {
        const auto& table = GusdUSD_TraverseTable::GetInstance();
        trav = table.FindTraversal(traversal);
        
        if(!trav) {
            UT_WorkBuffer buf;
            buf.sprintf("Failed locating traversal '%s'", traversal.c_str());
            return errContext.AddError(buf.buffer());
        }
    }
    return getInput(0) ? _ExpandPrims(ctx, trav, errContext)
                       : _CreateNewPrims(ctx, trav, errContext);
}                           
Пример #4
0
OP_ERROR
GusdSOP_usdimport::_ExpandPrims(OP_Context& ctx,
                                const GusdUSD_Traverse* traverse,
                                GusdUT_ErrorContext& err)
{
    if(!traverse)
        return UT_ERROR_NONE; // Nothing to do!

    fpreal t = ctx.getTime();

    // Construt a range and bind prims.
    bool packedPrims = !evalInt("import_class", 0, t);
    GA_AttributeOwner owner = packedPrims ?
        GA_ATTRIB_PRIMITIVE : GA_ATTRIB_POINT;
    GA_Range rng(gdp->getIndexMap(owner),
                 UTverify_cast<const GA_ElementGroup*>(_group));

    UT_Array<UsdPrim> rootPrims;
    GusdDefaultArray<UsdTimeCode> times;
    GusdDefaultArray<GusdPurposeSet> purposes;
    {
        GusdStageCacheReader cache;
        if(!GusdGU_USD::BindPrims(cache, rootPrims, *gdp, rng,
                                  /*variants*/ nullptr,
                                  &purposes, &times, &err)) {
            return err();
        }
    }
    if(!times.IsVarying())
        times.SetConstant(evalFloat("import_time", 0, t));

    // Traverse to find a new prim selection.
    UT_Array<GusdUSD_Traverse::PrimIndexPair> expandedPrims;
    {
        UT_UniquePtr<GusdUSD_Traverse::Opts> opts(traverse->CreateOpts());
        if(opts) {
            if(!opts->Configure(*this, t))
                return err();
        }

        if(!traverse->FindPrims(rootPrims, times, purposes, expandedPrims,
                                /*skip root*/ true, opts.get()))
            return err();
    }

    GA_AttributeFilter filter(GA_AttributeFilter::selectPublic());
    GusdGU_USD::AppendExpandedRefPoints(
        *gdp, *gdp, rng, expandedPrims, filter,
        GUSD_PATH_ATTR, GUSD_PRIMPATH_ATTR, &err);

    if(evalInt("import_delold", 0, t)) {
        if(packedPrims)
            gdp->destroyPrimitives(rng, /*and points*/ true);
        else
            gdp->destroyPoints(rng); // , GA_DESTROY_DEGENERATE);
    }
    return err();
}
Пример #5
0
OP_ERROR SOP_Density::cookMySop(OP_Context &context)

{
	//Lock inputs and cehck everything is ok
	OP_AutoLockInputs inputs(this);
	if (inputs.lock(context) >= UT_ERROR_ABORT){
		return error();
	}
	
	
	
	
	// duplicate source from input 0 
	duplicateSource(0,context);
	flags().timeDep = 1;
	
	//Varaibles
	fpreal ctime = context.getTime();//ctime is the currrent time e.g frame 1020 in a 24fps project is 1020.0/24 = 42.666666667
	float radius = SOP_Density::RADIUS(ctime);
	int neighbours = SOP_Density::NEIGHBOURS(ctime);
	UT_String attrstr;
	SOP_Density::ATTRIBNAME(attrstr,ctime);
	
	//create the actual attribute to store the density
	GA_RWHandleF densityAttr(gdp->addFloatTuple(GA_ATTRIB_POINT,attrstr,1));
	
	//create ppoint tree object
	GEO_PointTreeGAOffset pointtree;
	pointtree.build(gdp,NULL);
	
	GA_Offset ptoff;
	GA_FOR_ALL_PTOFF(gdp,ptoff){
		
		GEO_PointTree::IdxArrayType pointlist; //generate array to put points from ptree in
		GEO_PointTree::IdxArrayType distancelist; // generate array to put distance from ptree
		
		
		UT_Vector3 pos = gdp->getPos3(ptoff); //vector pos for points current position
		UT_FloatArray distance; //Array to store the calculated distance
		
		//ptree.findAllCloseIdx(pos,radius,pointlist) //find all points within the given radius
		int numclosept = pointtree.findNearestGroupIdx(pos,radius,neighbours,distancelist,distance);
		float weight = 1.0/numclosept;
		float sum = 0.0; //total sum of distance
		
		for(int i = 0;i<numclosept;++i){
			sum += distance(i);
		}
		sum *= weight;
		if(numclosept >= 1){
			densityAttr.set(ptoff,sum);
		}else{
			densityAttr.set(ptoff,-1.0);
		}
		
		
		
	}
Пример #6
0
int
GusdOBJ_usdcamera::applyInputIndependentTransform(OP_Context& ctx, UT_DMatrix4& mx)
{
    mx.identity();
    fpreal t = ctx.getTime();

    if(UsdGeomCamera cam = _LoadCamera(t, ctx.getThread()))
    {
        float frame = evalFloat(_frameIdx, 0, t);

        GfMatrix4d ctm(1.);
        bool stat = true;
        bool resetsXformStack = false;

        switch(evalInt("xformmode", 0, t))
        {
        case _POSTMULTCTM_TRANSFORM:
            stat = true;
            ctm = cam.ComputeLocalToWorldTransform(frame);
            break;
        case _CTM_TRANSFORM:
            stat = true;
            ctm = cam.ComputeParentToWorldTransform(frame);
            break;
        case _OBJ_TRANSFORM:
            // XXX: how do we reset xformStack here?
            // Is that (or should that
            // be) handled by the Compute calls above?
            stat = cam.GetLocalTransformation(&ctm, &resetsXformStack, frame);
            break;
        default: // _IGNORE_TRANSFORM:
            stat = true;
            ctm.SetIdentity();
            break;
        }
        if(!stat)
        {
            stealErrors(_errors, /*borrow*/ true);
            return 0;
        }

        mx = GusdUT_Gf::Cast(ctm);
    }
    return OBJ_Camera::applyInputIndependentTransform(ctx, mx);
}
Пример #7
0
std::string getStringParam(OP_Parameters& node, OP_Context &context,
	const std::string& label, bool trimspace)
{
	UT_String s;
	node.evalString(s, label.c_str(), 0, context.getTime());
	if(trimspace)
		s.trimSpace();

	return s.toStdString();
}
Пример #8
0
OP_ERROR
SOP_Cleave::cookMySop(OP_Context &context)
{

    const GA_PrimitiveGroup  *polyGroup;

    GEO_Primitive     	*prim;
    GQ_Detail           *gqd;
    int                  i,j,k;
    UT_Vector4           np,p;

    // Before we do anything, we must lock our inputs.  Before returning,
    //	we have to make sure that the inputs get unlocked.
    if (lockInputs(context) >= UT_ERROR_ABORT) return error();

    float now = context.getTime();
    duplicateSource(0, context, 0, 1);

    // Here we determine which groups we have to work on.  We only
    //	handle poly groups.

    UT_String groups;
    getGroups(groups);

    if (groups.isstring()) polyGroup = parsePrimitiveGroups(groups);
    else                   polyGroup = 0;

    if (error() >= UT_ERROR_ABORT) {
        unlockInputs();
        return error();
    }

    UT_Interrupt* boss = UTgetInterrupt();

    // Start the interrupt server
    boss->opStart("Cleaving Polys");


    // separate out all polys to be cleaved
    GA_PrimitiveGroup* cleave_group = gdp->newPrimitiveGroup("cleave",1);
    GA_PrimitiveGroup* not_cleave_group = gdp->newPrimitiveGroup("not_cleave",1);

    if (polyGroup) {

        GA_FOR_ALL_PRIMITIVES(gdp,prim)
        {

            if ( (prim->getTypeId()==GEO_PRIMPOLY) && (polyGroup->contains(prim)!=0))
                cleave_group->add(prim);
            else
                not_cleave_group->add(prim);
        }

    } else {
OP_ERROR
SOP_PrimGroupCentroid::cookMySop(OP_Context &context)
{
    fpreal                      now;
    int                       method, mode;

    now = context.getTime();

    if (lockInputs(context) >= UT_ERROR_ABORT)
        return error();

    // The partitioning mode.
    mode = MODE(now);

    // Find out which calculation method we are attempting.
    method = METHOD(now);

    // Binding geometry.
    if (nConnectedInputs() == 2)
    {
        // Duplicate the source.
        duplicateSource(0, context);

        // Bind to the centroids.  If the function returns 1, unlock
        // the inputs and return.
        if (bindToCentroids(now, mode, method))
        {
            unlockInputs();
            return error();
        }
    }
    // Creating centroids.
    else
    {
        // Clear out any previous data.
        gdp->clearAndDestroy();

        // Build the centroids.  If the function returns 1, unlock
        // the inputs and return.
        if (buildCentroids(now, mode, method))
        {
            unlockInputs();
            return error();
        }
    }

    unlockInputs();
    return error();
}
Пример #10
0
/* ******************************************************************************
*  Function Name : cookMySop()
*
*  Description : Cook this SOP node
*
*  Input Arguments : None
*
*  Return Value : OP_ERROR
*
***************************************************************************** */
OP_ERROR SOP_RF_Import::cookMySop(OP_Context & context)
{
   char GUI_str[128];
   OP_ERROR myError;

   float now = context.getTime();
   OP_Node::flags().timeDep = 1;

   myTotalPoints = 0;        // Set the NPT local variable value
   myCurrPoint   = 0;        // Initialize the PT local variable

   FNAME(myFileName, now);
   myFileType = FTYPE(now);

   disableParms();

   sprintf(GUI_str, "%s", "");
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_IMPORT_VER, 0, now);
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_IMPORT_INFO1, 0, now);
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_IMPORT_INFO2, 0, now);
   sprintf(GUI_str, "Version: %s", SOP_Version.c_str());
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_IMPORT_INFO3, 0, now);

#ifdef DEBUG
   std::cout << "cookMySop() - myFileType = " << myFileType << endl;
#endif

   switch(myFileType) {
         case 0:
            myError = ReadRFParticleFile(context);
            break;
         case 1:
            myError = ReadRFMeshFile(context);
            break;
         case 2:
            myError = ReadRFSDFile(context);
            break;
         case 3:
            myError = ReadRFRWCFile(context);
            break;
         default:
            return error();
      }

   myCurrPoint = -1;
   return myError;
}
Пример #11
0
OP_ERROR
GusdSOP_usdimport::cookInputGroups(OP_Context& ctx, int alone)
{
    if(!getInput(0))
        return UT_ERROR_NONE;

    int groupIdx = getParmList()->getParmIndex("import_group");
    int classIdx = getParmList()->getParmIndex("import_class");
    bool packedPrims = !evalInt(classIdx, 0, ctx.getTime());
    
    GA_GroupType groupType = packedPrims ?  
        GA_GROUP_PRIMITIVE : GA_GROUP_POINT;

    return cookInputAllGroups(ctx, _group, alone,
                              /* do selection*/ true,
                              groupIdx, classIdx, groupType);
}
Пример #12
0
/// Cook the SOP! This method does all the work
OP_ERROR SOP_ProceduralHolder::cookMySop( OP_Context &context )
{
	IECore::MessageHandler::Scope handlerScope( getMessageHandler() );
	
	// some defaults and useful variables
	float now = context.getTime();

	// force eval of our nodes parameters with our hidden parameter expression
	evalInt( "__evaluateParameters", 0, now );

	// update parameters on procedural from our Houdini parameters
	IECore::ParameterisedProceduralPtr procedural = IECore::runTimeCast<IECore::ParameterisedProcedural>( getParameterised() );

	// check for a valid parameterised on this SOP
	if ( !procedural )
	{
		UT_String msg( "Procedural Holder has no parameterised class to operate on!" );
		addError( SOP_MESSAGE, msg );
		return error();
	}
	
	if( lockInputs(context) >= UT_ERROR_ABORT )
	{
		return error();
	}
	
	// start our work
	UT_Interrupt *boss = UTgetInterrupt();
	boss->opStart("Building ProceduralHolder Geometry...");
	gdp->clearAndDestroy();
	
	setParameterisedValues( now );
	
	ToHoudiniCortexObjectConverterPtr converter = new ToHoudiniCortexObjectConverter( procedural );
	if ( !converter->convert( myGdpHandle ) )
	{
		addError( SOP_MESSAGE, "Unable to store procedural on gdp" );
	}
	
	// tidy up & go home!
	boss->opEnd();
	unlockInputs();
	return error();
}
Пример #13
0
OP_ERROR
SOP_Rain::cookMySop(OP_Context &context)
{
    //UT_Interrupt    *boss;
    if (error() < UT_ERROR_ABORT)
    {
        //boss = UTgetInterrupt();
        //boss->opStart("Start generating rain");
        
        fpreal now = TIME(context.getTime());
        long nPoints = NPOINTS( now );
        UT_Vector3 rainDirection = RAINDIRECTION(now);
        //rainDirection.normalize(); //TODO: check for (0,0,0) vector

        RainData rain(  now,
                        nPoints, BOUNDMIN (now), BOUNDMAX (now),
                        rainDirection, 
                        DICEMIN(now), DICEMAX(now), SEED(now),
                        SPEED (now),
                        SPEEDVARIENCE (now));

        if(rain.getAllocationState() == false || isPointsNumberChanged_ == true)
        {
            rain.allocate(nPoints);
        }
        if( rain.getAllocationState() == true && 
            ( rain.getCachedState() == false || isParameterChanged_ == true ) )
        {   
            rain.computeInitialPositions();
            rain.setCachedState(true);     
        }

        if (isPointsGenerated_ == false)
        {
            printf("Generate Points procedure\n");
            gdp->clearAndDestroy();

            generatePoints(gdp, nPoints);
            isPointsGenerated_ = true;
        }
        

        for (   GA_Iterator pr_it(gdp->getPrimitiveRange());
                !pr_it.atEnd();
                ++pr_it)
        {
            GEO_Primitive* prim = gdp->getGEOPrimitive(*pr_it);
            GA_Range range = prim->getPointRange();
            rain.shiftPositions( gdp, range);            
        }


     

        //boss->opEnd();
    }
    isParameterChanged_ = false;
    isPointsNumberChanged_ = false;
    //unlockInputs();
    return error();
}
Пример #14
0
OP_ERROR SOP_AddEdges::cookMySop(OP_Context &context)
{
	typedef dgal::simple_mesh<Imath::V3f>					simple_mesh;
	typedef dgal::EdgeIntersection<unsigned int, float> 	edge_intersection;
	typedef std::pair<unsigned int, unsigned int>			edge_type;

	hdk_utils::ScopedCook scc(*this, context, "Performing edges add");
	if(!scc.good())
		return error();

	double now = context.getTime();

	// inputs
	const GU_Detail* gdp0 = inputGeo(0);
	if (!gdp0 ) {
		SOP_ADD_FATAL(SOP_MESSAGE, "Not enough sources specified.");
	}

	unsigned int npoints0 = gdp0->points().entries();

	UT_String edgesAttrib;
	evalString(edgesAttrib, "edges_string", 0, now);
	std::string edgesAttribStr = edgesAttrib.toStdString();

	std::vector<std::string> toks;
	pystring::split(edgesAttribStr, toks);
	if(toks.empty())
	{
		duplicateSource(0, context);
		return error();
	}

	simple_mesh m, m2;
	simple_mesh* pm = NULL;
	std::vector<int> points_remap;
	std::vector<int> polys_remap;
	dgal::MeshRemapSettings<int> remap_settings(true, true, true, 0, 0, &points_remap, &polys_remap);
	std::map<std::string, unsigned int> new_points;

	// create new points
	{
		std::vector<edge_intersection> edgeints;

		std::string s = pystring::replace(edgesAttribStr, ",", " ");
		std::vector<std::string> toks;
		pystring::split(s, toks);

		for(unsigned int i=0; i<toks.size(); ++i)
		{
			// new point will be in form 'X-Y:f'
			if(toks[i].find('-') != std::string::npos)
			{
				s = pystring::replace(toks[i], "-", " ");
				s = pystring::replace(s, ":", " ");

				std::istringstream strm(s);
				edge_intersection ei;
				try {
					strm >> ei.m_point1 >> ei.m_point2 >> ei.m_u;
				}
				catch(const std::exception&) {
					continue;
				}

				new_points[toks[i]] = npoints0 + edgeints.size();
				edgeints.push_back(ei);
			}
		}

		if(new_points.empty())
		{
			// no new points means no point remapping
			remap_settings.m_genPointRemapping = false;
			remap_settings.m_identity_point_mapping = true;
		}
		else
		{
			dgal::addMeshPoints<GEO_Detail, std::vector<edge_intersection>::const_iterator>(
				*gdp0, m, edgeints.begin(), edgeints.end(), &points_remap, &polys_remap);
			pm = &m;
		}
	}
Пример #15
0
OP_ERROR SOP_SceneCacheSource::cookMySop( OP_Context &context )
{
	// make sure the state is valid
	if ( boost::indeterminate( m_static ) )
	{
		sceneChanged();
	}
	
	flags().setTimeDep( bool( !m_static ) );
	
	std::string file;
	if ( !ensureFile( file ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( file + " is not a valid .scc" ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	std::string path = getPath();
	Space space = getSpace();
	GeometryType geometryType = (GeometryType)this->evalInt( pGeometryType.getToken(), 0, 0 );
	
	UT_String shapeFilterStr;
	evalString( shapeFilterStr, pShapeFilter.getToken(), 0, 0 );
	UT_StringMMPattern shapeFilter;
	shapeFilter.compile( shapeFilterStr );
	
	UT_String p( "P" );
	UT_String attributeFilter;
	evalString( attributeFilter, pAttributeFilter.getToken(), 0, 0 );
	if ( !p.match( attributeFilter ) )
	{
		attributeFilter += " P";
	}
	
	ConstSceneInterfacePtr scene = this->scene( file, path );
	if ( !scene )
	{
		addError( SOP_ATTRIBUTE_INVALID, ( path + " is not a valid location in " + file ).c_str() );
		gdp->clearAndDestroy();
		return error();
	}
	
	MurmurHash hash;
	hash.append( file );
	hash.append( path );
	hash.append( space );
	hash.append( shapeFilterStr );
	hash.append( attributeFilter );
	hash.append( geometryType );
	hash.append( getObjectOnly() );
	
	if ( !m_loaded || m_hash != hash )
	{
		gdp->clearAndDestroy();
	}
	
	Imath::M44d transform = ( space == World ) ? worldTransform( file, path, context.getTime() ) : Imath::M44d();
	
	SceneInterface::Path rootPath;
	scene->path( rootPath );
	
	UT_Interrupt *progress = UTgetInterrupt();
	if ( !progress->opStart( ( "Cooking objects for " + getPath() ).c_str() ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted before it started" );
		gdp->clearAndDestroy();
		return error();
	}
	
	loadObjects( scene, transform, context.getTime(), space, shapeFilter, attributeFilter.toStdString(), geometryType, rootPath.size() );
	
	if ( progress->opInterrupt( 100 ) )
	{
		addError( SOP_ATTRIBUTE_INVALID, "Cooking interrupted" );
		gdp->clearAndDestroy();		
		m_loaded = false;
		m_hash = MurmurHash();
	}
	else
	{
		m_loaded = true;
		m_hash = hash;
	}
	
	progress->opEnd();
	
	return error();
}
Пример #16
0
OP_ERROR
SOP_Smoke_Source::cookMySop(OP_Context &context)
{
    // We must lock our inputs before we try to access their geometry.
    // OP_AutoLockInputs will automatically unlock our inputs when we return.
    // NOTE: Don't call unlockInputs yourself when using this!
    OP_AutoLockInputs inputs(this);
    if (inputs.lock(context) >= UT_ERROR_ABORT)
        return error();

    fpreal now = context.getTime();

    duplicateSource(0, context);

    // These three lines enable the local variable support.  This allows
    // $CR to get the red colour, for example, as well as supporting
    // any varmap created by the Attribute Create SOP.
    // Note that if you override evalVariableValue for your own
    // local variables (like SOP_Star does) it is essential you
    // still call the SOP_Node::evalVariableValue or you'll not
    // get any of the benefit of the built in local variables.

    // The variable order controls precedence for which attribute will be
    // be bound first if the same named variable shows up in multiple
    // places.  This ordering ensures point attributes get precedence.
    setVariableOrder(3, 2, 0, 1);

    // The setCur* functions track which part of the gdp is currently
    // being processed - it is what is used in the evalVariableValue
    // callback as the current point.  The 0 is for the first input,
    // you can have two inputs so $CR2 would get the second input's
    // value.
    setCurGdh(0, myGdpHandle);

    // Builds the lookup table matching attributes to the local variables.
    setupLocalVars();

    // Here we determine which groups we have to work on.  We only
    //	handle point groups.
    if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT &&
        (!myGroup || !myGroup->isEmpty()))
    {
        UT_AutoInterrupt progress("Flattening Points");

        // Handle all position, normal, and vector attributes.
        // It's not entirely clear what to do for quaternion or transform attributes.
        // We bump the data IDs of the attributes to modify in advance,
        // since we're already looping over them, and we want to avoid
        // bumping them all for each point, in case that's slow.
        UT_Array<GA_RWHandleV3> positionattribs(1);
        UT_Array<GA_RWHandleV3> normalattribs;
        UT_Array<GA_RWHandleV3> vectorattribs;
        GA_Attribute *attrib;
        GA_FOR_ALL_POINT_ATTRIBUTES(gdp, attrib)
        {
            // Skip non-transforming attributes
            if (!attrib->needsTransform())
                continue;

            GA_TypeInfo typeinfo = attrib->getTypeInfo();
            if (typeinfo == GA_TYPE_POINT || typeinfo == GA_TYPE_HPOINT)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    positionattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
            else if (typeinfo == GA_TYPE_NORMAL)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    normalattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
            else if (typeinfo == GA_TYPE_VECTOR)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    vectorattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
        }

        // Iterate over points up to GA_PAGE_SIZE at a time using blockAdvance.
        GA_Offset start;
        GA_Offset end;
        for (GA_Iterator it(gdp->getPointRange(myGroup)); it.blockAdvance(start, end);)
        {
            // Check if user requested abort
            if (progress.wasInterrupted())
                break;

            for (GA_Offset ptoff = start; ptoff < end; ++ptoff)
            {
                // This sets the current point that is beint processed to
                // ptoff.  This means that ptoff will be used for any
                // local variable for any parameter evaluation that occurs
                // after this point.
                // NOTE: Local variables and repeated parameter evaluation
                //       is significantly slower and sometimes more complicated
                //       than having a string parameter that specifies the name
                //       of an attribute whose values should be used instead.
                //       That parameter would only need to be evaluated once,
                //       the attribute could be looked up once, and quickly
                //       accessed; however, a separate point attribute would
                //       be needed for each property that varies per point.
                //       Local variable evaluation isn't threadsafe either,
                //       whereas attributes can be read safely from multiple
                //       threads.
                //
                //       Long story short: *Local variables are terrible.*
                myCurPtOff[0] = ptoff;
                float dist = DIST(now);
                UT_Vector3 normal;
                if (!DIRPOP())
                {
                    switch (ORIENT())
                    {
                        case 0 : // XY Plane
                            normal.assign(0, 0, 1);
                            break;
                        case 1 : // YZ Plane
                            normal.assign(1, 0, 0);
                            break;
                        case 2 : // XZ Plane
                            normal.assign(0, 1, 0);
                            break;
                    }
                }
                else
                {
                    normal.assign(NX(now), NY(now), NZ(now));
                    normal.normalize();
                }

                // Project positions onto the plane by subtracting
                // off the normal component.
                for (exint i = 0; i < positionattribs.size(); ++i)
                {
                    UT_Vector3 p = positionattribs(i).get(ptoff);
                    p -= normal * (dot(normal, p) - dist);
                    positionattribs(i).set(ptoff, p);
                }

                // Normals will now all either be normal or -normal.
                for (exint i = 0; i < normalattribs.size(); ++i)
                {
                    UT_Vector3 n = normalattribs(i).get(ptoff);
                    if (dot(normal, n) < 0)
                        n = -normal;
                    else
                        n = normal;
                    normalattribs(i).set(ptoff, n);
                }

                // Project vectors onto the plane through the origin by
                // subtracting off the normal component.
                for (exint i = 0; i < vectorattribs.size(); ++i)
                {
                    UT_Vector3 v = vectorattribs(i).get(ptoff);
                    v -= normal * dot(normal, v);
                    vectorattribs(i).set(ptoff, v);
                }
            }
        }
    }
OP_ERROR
SOP_PointsFromVoxels::cookMySop(OP_Context &context)
{
    bool                        cull, store;
    fpreal                      now, value;
    int                         rx, ry, rz;
    unsigned                    primnum;

    GA_Offset                   ptOff;
    GA_ROAttributeRef           input_attr_gah;
    GA_RWAttributeRef           attr_gah;
    GA_ROHandleS                input_attr_h;
    GA_RWHandleF                attr_h;

    const GU_Detail             *input_geo;
    const GEO_Primitive         *prim;
    const GEO_PrimVolume        *vol;

    UT_String                   attr_name;
    UT_Vector3                  pos;
    UT_VoxelArrayIteratorF      vit;

    now = context.getTime();

    if (lockInputs(context) >= UT_ERROR_ABORT)
    {
        return error();
    }

    // Get the primitive number.
    primnum = PRIM(now);

    // Check for culling.
    cull = CULL(now);

    store = STORE(now);

    // Clear out the detail since we only want our new points.
    gdp->clearAndDestroy();

    // Get the input geometry as read only.
    GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0));
    input_geo = gdl.getGdp();

    // Primitive number is valid.
    if (primnum < input_geo->getNumPrimitives())
    {
        // Get the primitive we need.
        prim = input_geo->primitives()(primnum);

        // The primitive is a volume primitive.
        if (prim->getTypeId().get() == GEO_PRIMVOLUME)
        {
            // Get the actual PrimVolume.
            vol = (const GEO_PrimVolume *)prim;

            // Get a voxel read handle from the primitive.
            UT_VoxelArrayReadHandleF    vox(vol->getVoxelHandle());

            // Attach the voxel iterator to the handle.
            vit.setHandle(vox);

            if (store)
            {
                // Try to find a 'name' attribute.
                input_attr_gah = input_geo->findPrimitiveAttribute("name");

                if (input_attr_gah.isValid())
                {
                    // Get this primitive's name.
                    input_attr_h.bind(input_attr_gah.getAttribute());
                    attr_name = input_attr_h.get(primnum);
                }

                // No name, so just use 'value'.
                else
                {
                    attr_name = "value";
                }

                // Add a float point attribute to store the values.
                attr_gah = gdp->addFloatTuple(GA_ATTRIB_POINT, attr_name, 1);

                // Attach an attribute handle.
                attr_h.bind(attr_gah.getAttribute());
            }

            // Culling empty voxels.
            if (cull)
            {
                // Iterate over all the voxels.
                for (vit.rewind(); !vit.atEnd(); vit.advance())
                {
                    // The voxel value.
                    value = vit.getValue();

                    // Skip voxels with a value of 0.
                    if (value == 0)
                    {
                        continue;
                    }

                    // Convert the voxel index to a position.
                    vol->indexToPos(vit.x(), vit.y(), vit.z(), pos);

                    // Create a point and set it to the position of the
                    // voxel.
                    ptOff = gdp->appendPointOffset();
                    gdp->setPos3(ptOff, pos);

                    // Store the value if necessary.
                    if (store)
                    {
                        attr_h.set(ptOff, value);
                    }
                }
            }

            else
            {
                // Get the resolution of the volume.
                vol->getRes(rx, ry, rz);

                // Add points for each voxel.
                ptOff = gdp->appendPointBlock(rx * ry * rz);

                // Iterate over all the voxels.
                for (vit.rewind(); !vit.atEnd(); vit.advance())
                {
                    // Convert the voxel index to a position.
                    vol->indexToPos(vit.x(), vit.y(), vit.z(), pos);

                    // Set the position for the current offset.
                    gdp->setPos3(ptOff, pos);

                    // Get and store the value if necessary.
                    if (store)
                    {
                        value = vit.getValue();
                        attr_h.set(ptOff, value);
                    }

                    // Increment the offset since the block of points we
                    // created is guaranteed to be contiguous.
                    ptOff++;
                }
            }
        }
        // Primitive isn't a volume primitive.
        else
        {
            addError(SOP_MESSAGE, "Not a volume primitive.");
        }
    }
    // Picked a primitive number that is out of range.
    else
    {
        addWarning(SOP_MESSAGE, "Invalid source index. Index out of range.");
    }

    unlockInputs();
    return error();
}
Пример #18
0
OP_ERROR
SOP_IdBlast::cookMySop(OP_Context &context)
{
    fpreal 		        now;
    exint                       id; 

    GA_Offset                   start, end;

    GA_PointGroup               *group;

    GA_ROAttributeRef           id_gah;
    GA_ROPageHandleI            id_ph;

    UT_String                   pattern;
    UT_WorkArgs                 tokens;

    IdOffsetMap                 id_map, srcid_map;
    GroupIdMapPair              pair;

    now = context.getTime();

    if (lockInputs(context) >= UT_ERROR_ABORT)
        return error();

    // Duplicate the incoming geometry.
    duplicateSource(0, context);

    // Get the id pattern.
    IDS(pattern, now);
    // If it's emptry, don't do anything.
    if (pattern.length() == 0)
    {
        unlockInputs();
        return error();
    }

    // Tokenize the range so we can handle multiple blocks.
    pattern.tokenize(tokens, " ");

    // Try to find the 'id' point attribute on the 1st input geometry.
    id_gah = gdp->findPointAttribute(GA_SCOPE_PUBLIC, "id");
    // If it doesn't exist, display a node error message and exit.
    if (id_gah.isInvalid())
    {
        addError(SOP_MESSAGE, "Input geometry has no 'id' attribute.");
        unlockInputs();
        return error();
    }
  
    // Bind the page handles to the attributes.
    id_ph.bind(id_gah.getAttribute());

    // Iterate over all the points we selected.
    for (GA_Iterator it(gdp->getPointRange()); it.blockAdvance(start, end); )
    {
        // Set the page handle to the start of this block.
        id_ph.setPage(start);
        
        // Iterate over all the points in the block.
        for (GA_Offset pt = start; pt < end; ++pt)
        {
            // Get the 'id' value for the point.
            id = id_ph.get(pt);
            id_map[id] = pt;
        }
    }

    // Create the group.
    group = createAdhocPointGroup(*gdp);

    //  Add the group and the id map to the pair.
    pair.first = group;
    pair.second = &id_map;

    // Iterate over each block in the tokens and add any ids to the group.
    for (int i=0; i < tokens.getArgc(); ++i)
    {
        UT_String id_range(tokens[i]);
        id_range.traversePattern(-1, &pair, addOffsetToGroup);
    }

    // Destroy the points.
    gdp->destroyPointOffsets(GA_Range(*group));

    unlockInputs();
    return error();
}
Пример #19
0
double SceneCacheNode<BaseType>::time( OP_Context context ) const
{
	return context.getTime() + CHgetManager()->getSecsPerSample();
}
Пример #20
0
OP_ERROR SOP_CudaParticles::cookMySop(OP_Context &context) {

	oldf = f;
	f =	context.getFrame();
	GEO_ParticleVertex* pvtx;

	double t = context.getTime();

	particlesSystem->dt = 1/(OPgetDirector()->getChannelManager()->getSamplesPerSec() * SUBSTEPS(t));
	particlesSystem->preview = PREVIEW(t);

	particlesSystem->partsLife = LIFE(t);
	particlesSystem->partsLifeVar = LIFEVAR(t);


	particlesSystem->velDamp = VELDAMP(t);
	particlesSystem->gravityStrength = GRAVITYSTR(t);
	particlesSystem->gravityDir = cu::make_float3(GRAVITYX(t),GRAVITYY(t),GRAVITYZ(t));
	particlesSystem->fluidStrength = FLUIDSTR(t);

	particlesSystem->noiseAmp = cu::make_float3(NOISEAMP(t),NOISEAMP(t),NOISEAMP(t));
	particlesSystem->noiseOct = NOISEOCT(t);
	particlesSystem->noiseFreq = NOISEFREQ(t);
	particlesSystem->noiseLac = NOISELACUN(t);
	particlesSystem->noiseOffset = cu::make_float3(NOISEOFFSETX(t),NOISEOFFSETY(t),NOISEOFFSETZ(t));

	particlesSystem->pointSize = POINTSIZE(t);
	particlesSystem->opacity = OPACITY(t);
	particlesSystem->startColor = cu::make_float3(STARTCOLORX(t),STARTCOLORY(t),STARTCOLORZ(t));
	particlesSystem->endColor = cu::make_float3(ENDCOLORX(t),ENDCOLORY(t),ENDCOLORZ(t));


	UT_Interrupt	*boss;

	OP_Node::flags().timeDep = 1;

    if (error() < UT_ERROR_ABORT) {
		boss = UTgetInterrupt();	

		// Start the interrupt server
		if (boss->opStart("Building Particles")){

			//gdp->clearAndDestroy();

			static float		 zero = 0.0;
			GB_AttributeRef partsAtt = gdp->addAttrib("cudaParticlesPreview", sizeof(int), GB_ATTRIB_INT, &zero);
			gdp->attribs().getElement().setValue<int>(partsAtt, particlesSystem->preview);

			GB_AttributeRef systemIdAtt = gdp->addAttrib("systemId", sizeof(int), GB_ATTRIB_INT, &zero);
			gdp->attribs().getElement().setValue<int>(systemIdAtt, particlesSystem->id);

			if (f < STARTFRAME(t)) {

				gdp->clearAndDestroy();
				particlesSystem->resetParticles();

			} else if (f == STARTFRAME(t)) {

				gdp->clearAndDestroy();
				particlesSystem->resetParticles();

				int maxParts = MAXPARTS(t);
				if (particlesSystem->nParts!=maxParts)
					particlesSystem->changeMaxParts(maxParts);

				//hSystem = (GEO_PrimParticle *)gdp->appendPrimitive(GEOPRIMPART);
				//hSystem->clearAndDestroy();

				GB_AttributeRef hVelocity = gdp->addPointAttrib("v", sizeof(UT_Vector3),GB_ATTRIB_VECTOR, 0);
				GB_AttributeRef hLife = gdp->addPointAttrib("life", sizeof(float)*2,GB_ATTRIB_FLOAT, 0);

				if(particlesSystem->preview!=1) {

					UT_Vector4 orig = UT_Vector4(0,0,0,1);

					

					for (int i = 0; i<particlesSystem->nParts; i++) {

						GEO_Point* newPoint = gdp->appendPoint();
						newPoint->setPos(orig);

						/*pvtx = hSystem->giveBirth();
						GEO_Point* ppt = pvtx->getPt();
						//ppt->getPos().assign(0,0,0,1);*/
						hSystemInit = 1;

					}
				}

			} else {

				if(particlesSystem->nParts != -1) {

					if(lockInputs(context) >= UT_ERROR_ABORT)
						return error();

					if(getInput(0)){

						GU_Detail* emittersInput = (GU_Detail*)inputGeo(0, context);
						GEO_PointList emittersList = emittersInput->points();
						int numEmitters = emittersList.entries();

						if (numEmitters != particlesSystem->nEmit) {
							delete particlesSystem->emitters;
							particlesSystem->nEmit = numEmitters;
							particlesSystem->emitters = new ParticlesEmitter[numEmitters];
						}

						GEO_AttributeHandle radAh, amountAh;
						GEO_AttributeHandle initVelAh, radVelAmpAh, noiseVelAmpAh,
							noiseVelOffsetAh, noiseVelOctAh, noiseVelLacAh, noiseVelFreqAh;

						radAh = emittersInput->getPointAttribute("radius");
						amountAh = emittersInput->getPointAttribute("amount");
						initVelAh = emittersInput->getPointAttribute("initVel");
						radVelAmpAh = emittersInput->getPointAttribute("radVelAmp");
						noiseVelAmpAh = emittersInput->getPointAttribute("noiseVelAmp");
						noiseVelOffsetAh = emittersInput->getPointAttribute("noiseVelOffset");
						noiseVelOctAh = emittersInput->getPointAttribute("noiseVelOct");
						noiseVelLacAh = emittersInput->getPointAttribute("noiseVelLac");
						noiseVelFreqAh = emittersInput->getPointAttribute("noiseVelFreq");

						for (int i = 0; i < numEmitters; i++) {

							UT_Vector4 emitPos = emittersList[i]->getPos();
							UT_Vector3 emitPos3(emitPos);

							particlesSystem->emitters[i].posX = emitPos.x();
							particlesSystem->emitters[i].posY = emitPos.y();
							particlesSystem->emitters[i].posZ = emitPos.z();

							radAh.setElement(emittersList[i]);
							amountAh.setElement(emittersList[i]);
							initVelAh.setElement(emittersList[i]);
							radVelAmpAh.setElement(emittersList[i]);
							noiseVelAmpAh.setElement(emittersList[i]);
							noiseVelOffsetAh.setElement(emittersList[i]);
							noiseVelOctAh.setElement(emittersList[i]);
							noiseVelLacAh.setElement(emittersList[i]);
							noiseVelFreqAh.setElement(emittersList[i]);

							particlesSystem->emitters[i].radius = radAh.getF(0);
							particlesSystem->emitters[i].amount = amountAh.getF(0);

							particlesSystem->emitters[i].velX = initVelAh.getF(0);
							particlesSystem->emitters[i].velY = initVelAh.getF(1);
							particlesSystem->emitters[i].velZ = initVelAh.getF(2);

							particlesSystem->emitters[i].radVelAmp = radVelAmpAh.getF(0);

							particlesSystem->emitters[i].noiseVelAmpX = noiseVelAmpAh.getF(0);
							particlesSystem->emitters[i].noiseVelAmpY = noiseVelAmpAh.getF(1);
							particlesSystem->emitters[i].noiseVelAmpZ = noiseVelAmpAh.getF(2);

							particlesSystem->emitters[i].noiseVelOffsetX = noiseVelOffsetAh.getF(0);
							particlesSystem->emitters[i].noiseVelOffsetY = noiseVelOffsetAh.getF(1);
							particlesSystem->emitters[i].noiseVelOffsetZ = noiseVelOffsetAh.getF(2);

							particlesSystem->emitters[i].noiseVelOct = noiseVelOctAh.getF(0);
							particlesSystem->emitters[i].noiseVelLac = noiseVelLacAh.getF(0);
							particlesSystem->emitters[i].noiseVelFreq = noiseVelFreqAh.getF(0);

						}
					} else {

						particlesSystem->nEmit = 0;

					}

					if(getInput(1)){

						GU_Detail* fluidInput = (GU_Detail*)inputGeo(1, context);

						GEO_AttributeHandle fluidIdAh= fluidInput->getDetailAttribute("solverId");
						fluidIdAh.setElement(fluidInput);

						int sId = fluidIdAh.getI();

						VHFluidSolver3D* curr3DSolver = VHFluidSolver3D::solverList[sId];

						particlesSystem->fluidSolver = curr3DSolver;

					}

						

					unlockInputs();


					if (f!=oldf) {

						particlesSystem->emitParticles();
						particlesSystem->updateParticles();

					}


					if(particlesSystem->preview!=1 && hSystemInit == 1) {

						cu::cudaMemcpy( particlesSystem->host_pos, particlesSystem->dev_pos,
							particlesSystem->nParts*sizeof(cu::float3), cu::cudaMemcpyDeviceToHost );

						GEO_Point* ppt;
						int i = 0;
						 UT_Vector4		p;

						FOR_ALL_GPOINTS(gdp, ppt) {

							ppt->getPos() = UT_Vector4(particlesSystem->host_pos[i*3],
													particlesSystem->host_pos[i*3+1],
													particlesSystem->host_pos[i*3+2],
													1);
							i++;

						}

						/*pvtx = hSystem->iterateInit();

						for (int i =0; i<particlesSystem->nParts; i++){
							pvtx->getPos().assign(particlesSystem->host_pos[i*3],
													particlesSystem->host_pos[i*3+1],
													particlesSystem->host_pos[i*3+2],
													1);
							pvtx = hSystem->iterateFastNext(pvtx);

						}*/

					}
				}

			}
Пример #21
0
OP_ERROR
SOP_FlexSolver::cookMySop(OP_Context &context)
{
    // We must lock our inputs before we try to access their geometry.
    // OP_AutoLockInputs will automatically unlock our inputs when we return.
    // NOTE: Don't call unlockInputs yourself when using this!
    OP_AutoLockInputs inputs(this);
    if (inputs.lock(context) >= UT_ERROR_ABORT)
        return error();

    // Now, indicate that we are time dependent (i.e. have to cook every
    // time the current frame changes).
    OP_Node::flags().timeDep = 1;

    // Channel manager has time info for us
    CH_Manager *chman = OPgetDirector()->getChannelManager();

    // This is the frame that we're cooking at...
    fpreal current_time = context.getTime();
    fpreal currframe = chman->getSample(context.getTime());
    fpreal reset = RESET(); // Find our reset frame...
    maxParticles = MAXPARTICLES();

    // Set up our source information...
    mySource = inputGeo(0, context);
    if (mySource)
    {
        mySourceVel = GA_ROHandleV3(mySource->findFloatTuple(GA_ATTRIB_POINT, "v", 3));

        // If there's no velocity, pick up the velocity from the normal
        if (mySourceVel.isInvalid())
        mySourceVel = GA_ROHandleV3(mySource->findFloatTuple(GA_ATTRIB_POINT, "N", 3));
    }

    if (currframe <= reset || !mySolver)
    {
        myLastCookTime = reset;
        initSystem(current_time);
    }
    else
    {
        //     // Set up the collision detection object
        //     const GU_Detail *collision = inputGeo(1, context);
        // if (collision)
        // {
        //     myCollision = new GU_RayIntersect;
        //     myCollision->init(collision);
        // }
        // else myCollision = 0;


        // This is where we notify our handles (if any) if the inputs have
        // changed.  This is normally done in cookInputGroups, but since there
        // is no input group, NULL is passed as the fourth argument.
        notifyGroupParmListeners(0, -1, mySource, NULL);

        // Now cook the geometry up to our current time
        // Here, we could actually re-cook the source input to get a moving
        // source...  But this is just an example ;-)

        currframe += 0.05;  // Add a bit to avoid floating point error
        while (myLastCookTime < currframe)
        {
            // Here we have to convert our frame number to the actual time.
            timeStep(chman->getTime(myLastCookTime));
            myLastCookTime += 1;
        }

        // if (myCollision) delete myCollision;

        // Set the node selection for the generated particles. This will 
        // highlight all the points generated by this node, but only if the 
        // highlight flag is on and the node is selected.
        select(GA_GROUP_POINT);
    }

    return error();
}
OP_ERROR SOP_InterpolatedCacheReader::cookMySop( OP_Context &context )
{
	flags().setTimeDep( true );
	
	if ( lockInputs( context ) >= UT_ERROR_ABORT )
	{
		return error();
	}
	
	gdp->stashAll();
	
	float time = context.getTime();
	float frame = context.getFloatFrame();
	
	UT_String paramVal;
	
	evalString( paramVal, "cacheSequence", 0, time );
	std::string cacheFileName = paramVal.toStdString();
	
	evalString( paramVal, "objectFixes", 0, time );
	std::string objectPrefix = paramVal.toStdString();
	evalString( paramVal, "objectFixes", 1, time );
	std::string objectSuffix = paramVal.toStdString();
	
	evalString( paramVal, "attributeFixes", 0, time );
	std::string attributePrefix = paramVal.toStdString();
	evalString( paramVal, "attributeFixes", 1, time );
	std::string attributeSuffix = paramVal.toStdString();
	
	evalString( paramVal, "transformAttribute", 0, time );
	std::string transformAttribute = paramVal.toStdString();
	
	int samplesPerFrame = evalInt( "samplesPerFrame", 0, time );
	InterpolatedCache::Interpolation interpolation = (InterpolatedCache::Interpolation)evalInt( "interpolation", 0, time );
	GroupingMode groupingMode = (GroupingMode)evalInt( "groupingMode", 0, time );
	
	// create the InterpolatedCache
	if ( cacheFileName.compare( m_cacheFileName ) != 0 || samplesPerFrame != m_samplesPerFrame || interpolation != m_interpolation )
	{
		try
		{
			float fps = OPgetDirector()->getChannelManager()->getSamplesPerSec();
			OversamplesCalculator calc( fps, samplesPerFrame );
			m_cache = new InterpolatedCache( cacheFileName, interpolation, calc );
		}
		catch ( IECore::InvalidArgumentException e )
		{
			addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}
		
		m_cacheFileName = cacheFileName;
		m_samplesPerFrame = samplesPerFrame;
		m_interpolation = interpolation;
	}
	
	if ( !m_cache )
	{
		addWarning( SOP_MESSAGE, "SOP_InterpolatedCacheReader: Cache Sequence not found" );
		unlockInputs();
		return error();
	}
	
	std::vector<InterpolatedCache::ObjectHandle> objects;
	std::vector<InterpolatedCache::AttributeHandle> attrs;
	
	try
	{
		m_cache->objects( frame, objects );
	}
	catch ( IECore::Exception e )
	{
		addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
		unlockInputs();
		return error();
	}
	
	duplicatePointSource( 0, context );
	
	GA_ElementGroupTable *groups = 0;
	if ( groupingMode == PointGroup )
	{
		groups = &gdp->pointGroups();
	}
	else if ( groupingMode == PrimitiveGroup )
	{
		groups = &gdp->primitiveGroups();
	}
	
	for ( GA_GroupTable::iterator<GA_ElementGroup> it=groups->beginTraverse(); !it.atEnd(); ++it )
	{
		GA_ElementGroup *group = it.group();
		if ( group->getInternal() || group->isEmpty() )
		{
			continue;
		}
		
		// match GA_ElementGroup name to InterpolatedCache::ObjectHandle
		std::string searchName = objectPrefix + group->getName().toStdString() + objectSuffix;
		std::vector<InterpolatedCache::ObjectHandle>::iterator oIt = find( objects.begin(), objects.end(), searchName );
		if ( oIt == objects.end() )
		{
			continue;
		}
		
		CompoundObjectPtr attributes = 0;
		
		try
		{
			m_cache->attributes( frame, *oIt, attrs );
			attributes = m_cache->read( frame, *oIt );
		}
		catch ( IECore::Exception e )
		{
			addError( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}
		
		const CompoundObject::ObjectMap &attributeMap = attributes->members();
		
		GA_Range pointRange;
		GA_Range primRange;
		GA_Range vertexRange;
		
		if ( groupingMode == PointGroup )
		{
			pointRange = gdp->getPointRange( (GA_PointGroup*)it.group() );
		}
		else if ( groupingMode == PrimitiveGroup )
		{
			primRange = gdp->getPrimitiveRange( (GA_PrimitiveGroup*)it.group() );
			const GA_PrimitiveList &primitives = gdp->getPrimitiveList();
			
			GA_OffsetList pointOffsets;
			GA_OffsetList vertOffsets;
			for ( GA_Iterator it=primRange.begin(); !it.atEnd(); ++it )
			{
				const GA_Primitive *prim = primitives.get( it.getOffset() );
				GA_Range primPointRange = prim->getPointRange();
				for ( GA_Iterator pIt=primPointRange.begin(); !pIt.atEnd(); ++pIt )
				{
					pointOffsets.append( pIt.getOffset() );
				}
				
				size_t numPrimVerts = prim->getVertexCount();
				for ( size_t v=0; v < numPrimVerts; v++ )
				{
					if ( prim->getTypeId() == GEO_PRIMPOLY )
					{
						vertOffsets.append( prim->getVertexOffset( numPrimVerts - 1 - v ) );
					}
					else
					{
						vertOffsets.append( prim->getVertexOffset( v ) );
					}
				}
			}
			
			pointOffsets.sortAndRemoveDuplicates();
			pointRange = GA_Range( gdp->getPointMap(), pointOffsets );
			vertexRange = GA_Range( gdp->getVertexMap(), vertOffsets );
		}
		
		// transfer the InterpolatedCache::Attributes onto the GA_ElementGroup
		for ( CompoundObject::ObjectMap::const_iterator aIt=attributeMap.begin(); aIt != attributeMap.end(); aIt++ )
		{
			Data *data = IECore::runTimeCast<Data>( aIt->second );
			if ( !data )
			{
				continue;
			}
			
			ToHoudiniAttribConverterPtr converter = ToHoudiniAttribConverter::create( data );
			if ( !converter )
 			{
 				continue;
 			}
			
			// strip the prefix/suffix from the GA_Attribute name
			std::string attrName = aIt->first.value();
			size_t prefixLength = attributePrefix.length();
			if ( prefixLength && ( search( attrName.begin(), attrName.begin()+prefixLength, attributePrefix.begin(), attributePrefix.end() ) == attrName.begin() ) )
			{
				attrName.erase( attrName.begin(), attrName.begin() + prefixLength );
			}
			
			size_t suffixLength = attributeSuffix.length();
			if ( suffixLength && ( search( attrName.end() - suffixLength, attrName.end(), attributeSuffix.begin(), attributeSuffix.end() ) == ( attrName.end() - suffixLength ) ) )
			{
				attrName.erase( attrName.end() - suffixLength, attrName.end() );
			}
			
			if ( attrName == "P" )
			{
				const V3fVectorData *positions = IECore::runTimeCast<const V3fVectorData>( data );
				if ( !positions )
				{
					continue;
				}
				
				size_t index = 0;
				size_t entries = pointRange.getEntries();
				const std::vector<Imath::V3f> &pos = positions->readable();
				
				// Attempting to account for the vertex difference between an IECore::CurvesPrimitive and Houdini curves.
				// As Houdini implicitly triples the endpoints of a curve, a cache generated from a single CurvesPrimitive
				// will have exactly four extra vertices. In this case, we adjust the cache by ignoring the first two and
				// last two V3fs. In all other cases, we report a warning and don't apply the cache to these points.
				if ( pos.size() - 4 == entries )
				{
					index = 2;
				}
				else if ( pos.size() != entries )
				{
					addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s contains %d points, while cache expects %d values for P." ) % group->getName().toStdString() % entries % pos.size() ).str().c_str() );
					continue;
				}
				
				/// \todo: try multi-threading this with a GA_SplittableRange
				for ( GA_Iterator it=pointRange.begin(); !it.atEnd(); ++it, ++index )
				{
					gdp->setPos3( it.getOffset(), IECore::convert<UT_Vector3>( pos[index] ) );
				}

			}
			else if ( groupingMode == PrimitiveGroup )
			{
				GA_Range currentRange;
				unsigned size = despatchTypedData<TypedDataSize, TypeTraits::IsVectorTypedData, DespatchTypedDataIgnoreError>( data );
				
				// check for existing attributes
				if ( gdp->findPrimitiveAttribute( attrName.c_str() ).isValid() && size == primRange.getEntries() )
				{
					currentRange = primRange;
				}
				else if ( gdp->findPointAttribute( attrName.c_str() ).isValid() && size == pointRange.getEntries() )
				{
					currentRange = pointRange;
				}
				else if ( gdp->findVertexAttribute( attrName.c_str() ).isValid() && size == vertexRange.getEntries() )
				{
					currentRange = vertexRange;
				}
				// fall back to Cortex standard inferred order
				else if ( size == primRange.getEntries() )
				{
					currentRange = primRange;
				}
				else if ( size == pointRange.getEntries() )
				{
					currentRange = pointRange;
				}
				else if ( size == vertexRange.getEntries() )
				{
					currentRange = vertexRange;
				}
				else
				{
					addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s: cache expects %d values for %s." ) % group->getName().toStdString() % size % attrName ).str().c_str() );
					continue;
				}
				
				converter->convert( attrName, gdp, currentRange );
			}
			else
			{
				converter->convert( attrName, gdp, pointRange );
			}
		}
		
		// if transformAttribute is specified, use to to transform the points
		if ( transformAttribute != "" )
		{
			const TransformationMatrixdData *transform = attributes->member<TransformationMatrixdData>( transformAttribute );
			if ( transform )
			{
				UT_Matrix4 matrix( IECore::convert<UT_Matrix4T<double> >( transform->readable().transform() ) );
				gdp->transformGroup( matrix, *group );
			}
			else
			{
				const TransformationMatrixfData *transform = attributes->member<TransformationMatrixfData>( transformAttribute );
				if ( transform )
				{
					UT_Matrix4 matrix = IECore::convert<UT_Matrix4>( transform->readable().transform() );
					gdp->transformGroup( matrix, *group );
				}
			}
		}
	}
	
	unlockInputs();
	return error();
}
Пример #23
0
OP_ERROR
GusdSOP_usdimport::_CreateNewPrims(OP_Context& ctx,
                                   const GusdUSD_Traverse* traverse,
                                   GusdUT_ErrorContext& err)
{
    fpreal t = ctx.getTime();

    UT_String file, primPath;
    evalString(file, "import_file", 0, t);
    evalString(primPath, "import_primpath", 0, t);
    if(!file.isstring() || !primPath.isstring()) {
        // Nothing to do.
        return UT_ERROR_NONE;
    }

    /* The prim path may be a list of prims.
       Additionally, those prim paths may include variants
       (eg., /some/model{variant=sel}/subscope ).
       Including multiple variants may mean that we need to access
       multiple stages. 

       Resolve the actual set of prims and variants first.*/

    UT_Array<SdfPath> primPaths, variants;
    if(!GusdUSD_Utils::GetPrimAndVariantPathsFromPathList(
           primPath, primPaths, variants, &err))
        return err();

    GusdDefaultArray<UT_StringHolder> filePaths;
    filePaths.SetConstant(file);

    // Get stage edits applying any of our variants.
    GusdDefaultArray<GusdStageEditPtr> edits;
    edits.GetArray().setSize(variants.size());
    for(exint i = 0; i < variants.size(); ++i) {
        if(!variants(i).IsEmpty()) {
            GusdStageBasicEdit* edit = new GusdStageBasicEdit;
            edit->GetVariants().append(variants(i));
            edits.GetArray()(i).reset(edit);
        }
    }
    
    // Load the root prims.
    UT_Array<UsdPrim> rootPrims;
    {
        rootPrims.setSize(primPaths.size());

        GusdStageCacheReader cache;
        if(!cache.GetPrims(filePaths, primPaths, edits,
                           rootPrims.data(),
                           GusdStageOpts::LoadAll(), &err))
            return err();
    }

    GusdDefaultArray<UsdTimeCode> times;
    times.SetConstant(evalFloat("import_time", 0, t));

    UT_String purpose;
    evalString(purpose, "purpose", 0, t);

    GusdDefaultArray<GusdPurposeSet> purposes;
    purposes.SetConstant(GusdPurposeSet(
                             GusdPurposeSetFromMask(purpose)|
                             GUSD_PURPOSE_DEFAULT));

    UT_Array<UsdPrim> prims;
    if(traverse) {
        // Before traversal, make a copy of the variants list.
        const UT_Array<SdfPath> variantsPreTraverse(variants);

        UT_Array<GusdUSD_Traverse::PrimIndexPair> primIndexPairs;

        UT_UniquePtr<GusdUSD_Traverse::Opts> opts(traverse->CreateOpts());
        if(opts) {
            if(!opts->Configure(*this, t))
                return err();
        }

        if(!traverse->FindPrims(rootPrims, times, purposes, primIndexPairs,
                                /*skip root*/ false, opts.get())) {
            return err();
        }

        // Resize the prims and variants lists to match the size of
        // primIndexPairs.
        exint size = primIndexPairs.size();
        prims.setSize(size);
        variants.setSize(size);

        // Now iterate through primIndexPairs to populate the prims
        // and variants lists.
        for (exint i = 0; i < size; i++) {
            prims(i) = primIndexPairs(i).first;
            exint index = primIndexPairs(i).second;

            variants(i) = index < variantsPreTraverse.size() ?
                          variantsPreTraverse(index) : SdfPath();
        }

    } else {
        std::swap(prims, rootPrims);
    }

    /* Have the resolved set of USD prims.
       Now create prims or points on the detail.*/

    bool packedPrims = !evalInt("import_class", 0, t);
    if(packedPrims) {
        UT_String vpLOD;
        evalString(vpLOD, "viewportlod", 0, t);


        GusdDefaultArray<UT_StringHolder> lods;
        lods.SetConstant(vpLOD);

        GusdGU_USD::AppendPackedPrims(*gdp, prims, variants,
                                      times, lods, purposes, &err);
    } else {
        GusdGU_USD::AppendRefPoints(*gdp, prims, GUSD_PATH_ATTR,
                                    GUSD_PRIMPATH_ATTR, &err);
    }
    return err();
}
Пример #24
0
/// Cook the SOP! This method does all the work
OP_ERROR SOP_OpHolder::cookMySop( OP_Context &context )
{
	IECore::MessageHandler::Scope handlerScope( getMessageHandler() );
	
	// some defaults and useful variables
	Imath::Box3f bbox( Imath::V3f(-1,-1,-1), Imath::V3f(1,1,1) );
	float now = context.getTime();

	// force eval of our nodes parameters with our hidden parameter expression
	evalInt( "__evaluateParameters", 0, now );

	// get our op
	IECore::OpPtr op = IECore::runTimeCast<IECore::Op>( getParameterised() );
	
	// check for a valid parameterised on this SOP
	if ( !op )
	{
		UT_String msg( "Op Holder has no parameterised class to operate on!" );
		addError( SOP_MESSAGE, msg );
		return error();
	}

	if( lockInputs(context)>=UT_ERROR_ABORT )
	{
		return error();
	}

	// start our work
	UT_Interrupt *boss = UTgetInterrupt();
	boss->opStart("Building OpHolder Geometry...");
	gdp->clearAndDestroy();
	
	setParameterisedValues( now );
	
	try
	{
		// make our Cortex op do it's thing...
		op->operate();

		// pass ourselves onto the GR_Cortex render hook
		IECoreHoudini::NodePassData data( this, IECoreHoudini::NodePassData::CORTEX_OPHOLDER );
		GA_RWAttributeRef attrRef = gdp->createAttribute( GA_ATTRIB_DETAIL, GA_SCOPE_PRIVATE, "IECoreHoudiniNodePassData", NULL, NULL, "blinddata" );
		GA_Attribute *attr = attrRef.getAttribute();
		const GA_AIFBlindData *blindData = attr->getAIFBlindData();
		blindData->setDataSize( attr, sizeof(IECoreHoudini::NodePassData), &data );

		// if our result is a visible renderable then set our bounds on our output gdp
		const IECore::Object *result = op->resultParameter()->getValue();
		IECore::ConstVisibleRenderablePtr renderable = IECore::runTimeCast<const IECore::VisibleRenderable>( result );
		if ( renderable )
		{
			Imath::Box3f bbox = renderable->bound();
			gdp->cube( bbox.min.x, bbox.max.x, bbox.min.y, bbox.max.y, bbox.min.z, bbox.max.z, 0, 0, 0, 1, 1 );
		}
	}
	catch( boost::python::error_already_set )
	{
		addError( SOP_MESSAGE, "Error raised during Python evaluation!" );
		IECorePython::ScopedGILLock lock;
		PyErr_Print();
	}
	catch( const IECore::Exception &e )
	{
		addError( SOP_MESSAGE, e.what() );
	}
	catch( const std::exception &e )
	{
		addError( SOP_MESSAGE, e.what() );
	}
	catch( ... )
	{
		addError( SOP_MESSAGE, "Caught unknown exception!" );
	}

	// tidy up & go home!
	boss->opEnd();
	unlockInputs();
	return error();
}
OP_ERROR
SOP_groupAsAttr::cookMySop(OP_Context &context)
{
    // We must lock our inputs before we try to access their geometry.
    // OP_AutoLockInputs will automatically unlock our inputs when we return.
    // NOTE: Don't call unlockInputs yourself when using this!
    OP_AutoLockInputs inputs(this);
    if (inputs.lock(context) >= UT_ERROR_ABORT)
        return error();

    // Duplicate our incoming geometry with the hint that we only
    // altered points.  Thus, if our input was unchanged, we can
    // easily roll back our changes by copying point values.
    duplicatePointSource(0, context);

    fpreal t = context.getTime();

    // We evaluate our parameters outside the loop for speed.  If we
    // wanted local variable support, we'd have to do more setup
    // (see SOP_Flatten) and also move these inside the loop.
    int get_PointGrp, get_PrimGrp;

    get_PointGrp = getPointToggle(t);
    get_PrimGrp = getPrimToggle(t);

    debug = debugMe(t);

    cout << "debug      :" << debug << endl;
    cout << "get ptGrp  :" << get_PointGrp << endl;
    cout << "get ptimGrp:" << get_PrimGrp << endl;


    if (error() >= UT_ERROR_ABORT)
        return error();

    // Here we determine which groups we have to work on.  We only
    // handle point groups.
    if (cookInputGroups(context) >= UT_ERROR_ABORT)
    {
        return error();
    }


    //if we have chosen a point group
    if(get_PointGrp)
    {
        cout << "we are in points now!!" << endl;
        if(debug)
        {
            cout << "-------------------------------" <<endl;
            cout << "--*>YOU HAVE CHOSEN A POINT GROUP" << endl;
        }

        groupToAttrPoints("ptGroupName", debug);

    }

    //IF WE HAVE CHOSEN TO DEAL WITH PRIMITIVES
    if(get_PrimGrp)
    {
        //set our flag to signal that we have chosen to use the prim attr
        if(debug)
        {
            cout << "-------------------------------" <<endl;
            cout << "--*>YOU HAVE CHOSEN A PRIM GROUP" << endl;
        }
        //if we have never checked this option before
        if(!primChanged)
        {
            //deal with the prim groups if any as attrs
            groupToAttrPrims("primGroupName", debug);
            //change our flag to on
            primChanged = true;
        }

    }
    else
    {
        //otherwise if we have just unchecked the prim attrs
        if(primChanged)
        {
            //destroy the attr and flag our check
            gdp->destroyAttribute(GA_ATTRIB_PRIMITIVE, "primGroupName");
            primChanged = false;
        }


    }

    // If we've modified P, and we're managing our own data IDs,
    // we must bump the data ID for P.
    if (!myGroup || !myGroup->isEmpty())
        gdp->bumpAllDataIds();
//        gdp->getP()->bumpDataId();

    return error();
}
Пример #26
0
OP_ERROR
SOP_PrimCentroid::cookMySop(OP_Context &context)
{
    fpreal                      now;
    int                         method;

    const GA_Attribute          *source_attr;
    const GA_AttributeDict      *dict;
    GA_AttributeDict::iterator  a_it;
    GA_Offset                   ptOff;
    GA_RWAttributeRef           n_gah;
    GA_RWHandleV3               n_h;

    const GEO_Primitive         *prim;

    const GU_Detail             *input_geo;

    UT_BoundingBox              bbox;
    UT_String                   pattern, attr_name;
    UT_WorkArgs                 tokens;

    now = context.getTime();

    if (lockInputs(context) >= UT_ERROR_ABORT)
        return error();

    // Clear out any previous data.
    gdp->clearAndDestroy();

    // Get the input geometry as read only.
    GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0));
    input_geo = gdl.getGdp();

    // Find out which calculation method we are attempting.
    method = METHOD(now);

    // Create the standard point normal (N) attribute.
    n_gah = gdp->addNormalAttribute(GA_ATTRIB_POINT);

    // Bind a read/write attribute handle to the normal attribute.
    n_h.bind(n_gah.getAttribute());

    // Construct an attribute reference map to map attributes.
    GA_AttributeRefMap hmap(*gdp, input_geo);

    // Get the attribute selection string.
    ATTRIBUTES(pattern, now);

    // Make sure we entered something.
    if (pattern.length() > 0)
    {
        // Tokenize the pattern.
        pattern.tokenize(tokens, " ");

        // The primitive attributes on the incoming geometry.
        dict = &input_geo->primitiveAttribs();

        // Iterate over all the primitive attributes.
        for (a_it=dict->begin(GA_SCOPE_PUBLIC); !a_it.atEnd(); ++a_it)
        {
            // The current attribute.
            source_attr = a_it.attrib();

            // Get the attribute name.
            attr_name = source_attr->getName();

            // If the name doesn't match our pattern, skip it.
            if (!attr_name.matchPattern(tokens))
                continue;

            // Create a new point attribute on the current geometry
            // that is the same as the source attribute.  Append it and
            // the source to the map.
            hmap.append(gdp->addPointAttrib(source_attr).getAttribute(),
                        source_attr);
        }

        // Copy local variables.
        if (COPY(now))
        {
            // Traverse the variable names on the input geometry and attempt to
            // copy any that match to our new geometry.
            input_geo->traverseVariableNames(
                SOP_PrimCentroid::copyLocalVariables,
                gdp
            );
        }
    }

    // Get the list of input primitives.
    const GA_PrimitiveList &prim_list = input_geo->getPrimitiveList();

    // Add points for each primitive.
    ptOff = gdp->appendPointBlock(input_geo->getNumPrimitives());

    // Iterate over primitives using pages.
    for (GA_Iterator it(input_geo->getPrimitiveRange()); !it.atEnd(); ++it)
    {
        // Get the primitive from the list.
        prim = (const GEO_Primitive *) prim_list.get(*it);

        if (method)
        {
            // Get the bounding box for the primitive and set the point's
            // position to be the center of the box.
            prim->getBBox(&bbox);
            gdp->setPos3(ptOff, bbox.center());
        }
        else
            // Set the point's position to be the bary center of the primitive
            gdp->setPos3(ptOff, prim->baryCenter());

        // Set the point's normal to be the normal of the primitive.
        n_h.set(ptOff, prim->computeNormal());

        // If we are copying attributes, copy the primitive attributes from
        // the current primitive to the new point.
        if (hmap.entries() > 0)
            hmap.copyValue(GA_ATTRIB_POINT, ptOff, GA_ATTRIB_PRIMITIVE, *it);

        // Increment the point offset.
        ptOff++;
    }

    unlockInputs();
    return error();
}
Пример #27
0
OP_ERROR SOP_UniPdist::cookMySop(OP_Context &context)
{
    // Before we do anything, we must lock our inputs.  Before returning,
    // we have to make sure that the inputs get unlocked.
    if (lockInputs(context) >= UT_ERROR_ABORT)
	return error();

    // Duplicate input geometry
    duplicateSource(0, context);

	float time = context.getTime();
	float dist = evalFloat(distanceName.getToken(), 0, time);
	
	GA_PointGroup *removeGroup = gdp->newPointGroup(REMOVE_GROUP_NAME);
	GA_PointGroup *keepGroup   = gdp->newPointGroup(KEEP_GROUP_NAME);
	

    // Flag the SOP as being time dependent (i.e. cook on time changes)
    flags().timeDep = 1;

	//Create a removeAttrib
	GA_RWHandleI removeAttrib(gdp->addIntTuple(GA_ATTRIB_POINT, "__remove__", 1));
	
	//Creating PointTree
	GEO_PointTreeGAOffset pttree;
	//Build PointTree with all the points
	pttree.build(gdp,NULL);
	
	
	//Create the Array wich holds the distance for the current point in the for loop
	UT_FloatArray ptdist;
	
	// Index offset
	const GA_IndexMap points = gdp->getPointMap();
	GA_Size ptoffsetindex;
	ptoffsetindex = points.offsetSize()-points.indexSize();
	

	//set all
	for (GA_Iterator ptoff(gdp->getPointRange()); !ptoff.atEnd(); ++ptoff) 
	{
		removeAttrib.set(*ptoff,0);
	}

	
	
	
	
	// loop over all points, find second closest point
	for (GA_Iterator ptoff(gdp->getPointRange()); !ptoff.atEnd(); ++ptoff)

	{
		int removeMe;
		removeMe = int(removeAttrib.get(*ptoff));
		if(removeMe)
		{
			removeGroup->addIndex(*ptoff-ptoffsetindex);
			continue;
		}
			
		// Create the Array which holds a list sorted on distance to current point in the for loop
		GEO_PointTree::IdxArrayType plist; //plist
		UT_Vector3 pos = gdp->getPos3(*ptoff); // create pos
		pttree.findAllCloseIdx(pos,dist,plist); // find all points within the search radius
		
		
		unsigned int tempListP = plist.entries(); //create a int for entries in the array

		for(int i=0;i < tempListP; ++i)
		{
			removeAttrib.set(plist[i],1); //set the tempList points to be removed
		}
		removeAttrib.set(*ptoff,0);
		keepGroup->addIndex(*ptoff-ptoffsetindex);
	}
	pttree.clear(); //clear the pointtree
	
	
    unlockInputs();
    return error();
}
Пример #28
0
/* ******************************************************************************
*  Function Name :  cookMySop()
*
*  Description :
*
*  Input Arguments : None
*
*  Return Value :
*
***************************************************************************** */
OP_ERROR SOP_RF_Export::cookMySop(OP_Context & context)
{
   UT_Vector3 trans, rot, scale, up, shear;
   char GUI_str[128];
   OP_ERROR myError;

   OP_Node::flags().timeDep = 1;

   float * myBeginEnd_ptr = myBeginEnd;
   float now = context.getTime();

   disableParms();

   // Evaluate the GUI parameters
   myFileFormat = (int)FILE_FORMAT(now);
   myStaticAnim = (bool)ANIM(now);
   myMode = (bool)MODE(now);
   BEGIN_END(myBeginEnd_ptr, now);
   FNAME(myFileName, now);
   myEchoData =   ECHO_CONSOLE(now);


   disableParms();

   sprintf(GUI_str, "%s", "");
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_EXPORT_INFO1, 0, now);
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_EXPORT_INFO2, 0, now);
   sprintf(GUI_str, "Version: %s", SOP_Version.c_str());
   setString((UT_String)GUI_str, CH_STRING_LITERAL, ARG_RF_EXPORT_INFO3, 0, now);


   // If there has been a error from the previous callback, report it
   if(myCallBackFlags) {
         return(reportCallBackErrors(myCallBackFlags));
      }


#ifdef DEBUG
   std::cout << "myFileFormat " << myFileFormat << endl;
#endif

   switch(myFileFormat) {
         case SD_FILE:
            myError = writeSDFile(context);
            break;

         case BIN_FILE:
            myError = writeBINFile(context);
            break;

         case RWC_FILE:
            myError = writeRWCFile(context);
            break;

         case MESH_FILE:
            myError = writeMeshFile(context);
            break;

         default:
            return error();
      }

   return myError;
}
Пример #29
0
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();
};
Пример #30
0
OP_ERROR
SOP_IntersectRay::cookMySop(OP_Context &context)
{
    double t;
    float  edgelength, primarea, generatepoints;
    int    verbose;

    // We optionally add points in self-penetration places:
    GB_PointGroup          *hitPointsGroup;
    UT_RefArray<UT_Vector3> hitPoints;

    if (lockInputs(context) >= UT_ERROR_ABORT)
	    return error();

    t = context.getTime();
    duplicatePointSource(0, context);

    edgelength     = EDGELENGTH(t);
    primarea       = PRIMAREA(t);
    verbose        = VERBOSE(t);
    generatepoints = GENERATEPOINTS(t);

    // Normals:
    GEO_AttributeHandle  nH;
    GEO_AttributeHandle  cdH;
    nH   = gdp->getAttribute(GEO_POINT_DICT, "N");
    cdH  = gdp->getAttribute(GEO_POINT_DICT, "Cd");
   

    // RayInfo parms:
    //float max = 1E18f; // Max specified by edge length...
    float min = 0.0f;
    float tol = 1e-1F;

    // Rayhit objects:
    GU_RayFindType  itype     = GU_FIND_ALL;   
    GU_RayIntersect intersect = GU_RayIntersect(gdp);

    // Profile:
    //Timer timer = Timer();
    //float rayhit_time = 0;
    //float vertex_time = 0;

    // Here we determine which groups we have to work on. 
    if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT)
    {
        UT_AutoInterrupt progress("Checking for self-intersections...");
        const GEO_Primitive   *ppr;
        FOR_ALL_GROUP_PRIMITIVES(gdp, myGroup, ppr)
	    {
             // Check if user requested abort
             if (progress.wasInterrupted())
                break;

            // Get rid of primitives smaller than primarea:
            if ( ppr->calcArea() < primarea )
                continue;

            for (int j = 0; j < ppr->getVertexCount() - 1; j++)
            {
                // Get data;
                // TODO: This is extremally inefficent.
                // TODO: Why do we crash with uv vetrex attributes!? 
                const GEO_Vertex ppv1 = ppr->getVertex(j);
                const GEO_Vertex ppv2 = ppr->getVertex(j+1);
                const GEO_Point *ppt1 = ppv1.getPt();
                const GEO_Point *ppt2 = ppv2.getPt();
               
                // Vertices positions:
                UT_Vector3 p1 = ppt1->getPos();
                UT_Vector3 p2 = ppt2->getPos();

                // Ray direction:
                p2   = p2 - p1;
                // Get rid of edges shorter than edgelength:
                if (p2.length() < edgelength)
                    continue;
                // hit info with max distance equal edge length:
                GU_RayInfo  hitinfo = GU_RayInfo(p2.length(), min, itype, tol); 
                p2.normalize();

                // Send ray:
                if (intersect.sendRay(p1, p2, hitinfo))
                {  
                    UT_RefArray<GU_RayInfoHit> hits = *(hitinfo.myHitList);
                    for(int j = 0; j < hits.entries(); j++)
                    {
                        const GEO_Primitive *prim = hits[j].prim;
                        const GEO_PrimPoly  *poly = (const GEO_PrimPoly *) prim; //TODO: Prims only?
                        // We are interested only ff points are not part of prims...:
                        if (poly->find(*ppt1) == -1 && poly->find(*ppt2)== -1)
                        {
                            if (verbose)
                                printf("Edge: %i-%i intersects with prim:%d \n",ppt1->getNum(), ppt2->getNum(), prim->getNum());

                            // Save hit position as points:
                            if (generatepoints)
                            {
                                UT_Vector4 pos;
                                float u = hits[j].u; 
                                float v = hits[j].v;
                                if (!prim->evaluateInteriorPoint(pos, u, v))
                                    hitPoints.append(pos);
                            }

                            // TODO: Should I indicate penetration with red color on both ends of edge?:
                            cdH.setElement(ppt1);
                            cdH.setV3(UT_Vector3(1.0, 0.0, 0.0));
                            cdH.setElement(ppt2);
                            cdH.setV3(UT_Vector3(1.0, 0.0, 0.0));
                        }
                        
                    }
                }
            }
	    } 
     
   
    if (generatepoints)
    {
        hitPointsGroup = gdp->newPointGroup("__self_penetrate", false);
        for (int i = 0; i < hitPoints.entries(); i++)
        {
            GEO_Point *point;
            point = gdp->appendPoint();
            hitPointsGroup->add(point);
            point->setPos(hitPoints(i));
        }
    }
    
    }