Пример #1
0
// When mantra determines that the bounding box needs to be rendered, the 
// render method is called. At this point, the procedural can either 
// generate geometry (VRAY_Procedural::openGeometryObject()) or it can 
// generate further procedurals (VRAY_Procedural::openProceduralObject()).
void
VRAY_ieProcedural::render()
{
	initialisePython();
	ParameterisedProceduralPtr parameterisedProcedural = 0;
	ScopedGILLock giLock;
	try
	{
		object ieCore = g_mainModuleNamespace["IECore"];
		object classLoader = ieCore.attr( "ClassLoader" ).attr( "defaultProceduralLoader" )();
		object procedural = classLoader.attr( "load" )( m_className.buffer(), m_classVersion )();
		boost::python::list params;
		UT_WorkArgs argv;
		if (m_parameterString.tokenize(argv, ","))
		{
            // The Cortex Mantra Inject otl parses the parameters of a 
            // SOP_ProceduralHolder and replaces empty values with a '!' 
            // character to make them easier to parse here.
            // 
            // This hack is upsetting, a pure python procedural in the style 
            // of IECoreRI iePython.dso could parse these parameters correctly
            // like python/IECoreRI/ExecuteProcedural.py
			for (int i = 0; i < argv.getArgc(); i++) 
			{
				std::string s(argv[i]);
				if (s == "!")
				{
					params.append(std::string(""));
				}
				else
				{
					params.append(s);
				}
			}
		}
		object parameterParser = ieCore.attr( "ParameterParser" )();
		parameterParser.attr( "parse" )( params, procedural.attr( "parameters" )() );
		parameterisedProcedural = extract<ParameterisedProceduralPtr>( procedural );
	}
	catch( const error_already_set &e )
	{
		PyErr_Print();
	}
	catch( const std::exception &e )
	{
		msg( Msg::Error, "VRAY_ieProcedural", e.what() );
	}
	catch( ... )
	{
		msg( Msg::Error, "VRAY_ieProcedural", "Caught unknown exception" );
	}
	if( parameterisedProcedural )
	{
		IECoreMantra::RendererPtr renderer = new IECoreMantra::Renderer( this );
		parameterisedProcedural->render( renderer.get(), false, false, true, true ); 
	}
}
Пример #2
0
// The initialize method is called when the procedural is created. 
// Returning zero (failure) will abort the rendering of this procedural.
// The bounding box passed in is the user defined bounding box. 
// If the user didn't specify a bounding box, then the box will be NULL
int
VRAY_ieWorld::initialize(const UT_BoundingBox *box)
{
	if ( box )
    {
		m_bound = convert<Imath::Box3f> ( *box );
	}
	import( "ieworldfile", m_worldFileName);
	import( "ieworldremove", &m_remove, 1);
	if( access( m_worldFileName.buffer(), R_OK|F_OK ) == -1 )
	{
		msg( Msg::Warning, "VRAY_ieWorld", format("Failed to find ieworld cache file: %s") % m_worldFileName.buffer() );
		return 0;
	}
	return 1;	
}
Пример #3
0
// When mantra determines that the bounding box needs to be rendered, the 
// render method is called. At this point, the procedural can either 
// generate geometry (VRAY_Procedural::openGeometryObject()) or it can 
// generate further procedurals (VRAY_Procedural::openProceduralObject()).
void
VRAY_ieWorld::render()
{
	ConstVisibleRenderablePtr renderable = 0;
	try
	{
		ReaderPtr reader = Reader::create( m_worldFileName.buffer() );
		renderable = runTimeCast<VisibleRenderable>( reader->read() );
	}
	catch ( IECore::Exception e )
	{
		msg( Msg::Warning, "VRAY_ieWorld", format("Failed to load ieworld cache file: %s") % m_worldFileName.buffer() );
	}
	if ( !renderable )
	{
		msg( Msg::Warning, "VRAY_ieWorld", format("Failed to read ieworld cache file: %s") % m_worldFileName.buffer() );
	}
	IECoreMantra::RendererPtr renderer = new IECoreMantra::Renderer( this );
	renderable->render( renderer.get() );
}
Пример #4
0
ratReader::ratReader(Read *r, int fd): Reader(r)
{
    // Init: 
    buffer = NULL;
    loaded = false;
    rat    = NULL;
    use_scanline_engine = true;
    parms = new IMG_FileParms();
    
    // Read knobs:
    ratReaderFormat* rrf = dynamic_cast<ratReaderFormat*>(r->handler());
    if (rrf)
    {
        if (rrf->reverse_scanlines())
            parms->orientImage(IMG_ORIENT_LEFT_FIRST, IMG_ORIENT_TOP_FIRST);

        use_scanline_engine = rrf->use_scanline_engine(); 
    }
    else
        parms->orientImage(IMG_ORIENT_LEFT_FIRST, IMG_ORIENT_Y_NONE);

    // Set some of the settings, which are assumed currently by both ::engines. 
    // Leaving them as they are would require some serious switches in logic bellow.
    parms->setDataType(IMG_FLOAT);
    parms->setInterleaved(IMG_INTERLEAVED);
    parms->setComponentOrder(IMG_COMPONENT_RGBA);
    
    // Create and open rat file, get stats:
    rat = IMG_File::open(r->filename(), parms);

    // TODO: Meta data attempt:
    #if defined(DEBUG)
    UT_String info;
    rat->getAdditionalInfo(info);
    iop->warning("Rat info: %s\n", info.buffer());
    for (int i = 0; i < rat->getNumOptions(); i++)
    {
        iop->warning("%s: %s", rat->getOptionName(i), rat->getOptionValue(i));
    }
    UT_SharedPtr<UT_Options> opt;
    UT_WorkBuffer wbuf;
    if (opt = rat->imageTextureOptions())
    {
        wbuf.strcpy("DSM Options: ");
        opt->appendPyDictionary(wbuf);
        iop->warning("Options %i: %s\n", opt->getNumOptions(), wbuf.buffer());
    }
    #endif
    if (!rat)
    {
        iop->error("Failed to open .rat file.");
    }
    const IMG_Stat &stat = rat->getStat();
    depth = 0;
    #if defined(DEBUG)
    iop->warning("Rat opened: %s", r->filename());
    #endif

    // Since RAT can store varying bitdepth per plane, pixel-byte algebra doesn't 
    // help in finding out a number of channels. We need to iterate over planes. 
    for (int i = 0; i < stat.getNumPlanes(); i++)
    {
        IMG_Plane *plane = stat.getPlane(i);

        // The easiest yet not unequivocal way to determine 2d versus deep RAT files:
        if (!strcmp(plane->getName(), "Depth-Complexity"))
            iop->warning("ratReader will treat DCM files as a 2d images. (ignoring deep pixels)");

        #if defined(DEBUG)
        iop->warning("Plane name: %s", plane->getName());
        #endif
        depth += IMGvectorSize(plane->getColorModel()); 
    } 

    ChannelSet mask;
    for (int i = 0; i < stat.getNumPlanes(); i++)
    {
        IMG_Plane *plane = stat.getPlane(i);
        const int  nchan = IMGvectorSize(plane->getColorModel());

        for (int j = 0; j < nchan; j++)
        {
            std::string chan = std::string(plane->getComponentName(j) ? plane->getComponentName(j): "r"); 

            if      (chan == "r") chan = "red"; 
            else if (chan == "g") chan = "green";
            else if (chan == "b") chan = "blue"; 
            else if (chan == "a") chan = "alpha";

            std::string chan_name = std::string(plane->getName()) + std::string(".") + chan;
            std::set<Channel> channels;
            lookupChannels(channels, chan_name.c_str());

            if (!channels.empty()) 
            {
                for (std::set<Channel>::iterator it = channels.begin(); it != channels.end(); it++) 
                {
                    Channel channel = *it;
                    channel_map[channel]= chan_name.c_str();
                    std::pair<int, int> idx(i, j);
                    rat_chan_index[channel] = idx;
                     
                    #if defined(DEBUG)
                    iop->warning("Rat %s (%i,%i) becomes %s", chan_name.c_str(), i, j, getName(channel));
                    #endif
                    mask += channel;
                }
            }
            else
                iop->warning("Can't create a channel from %s", chan_name.c_str());
        }
    }
    // Set info:
    #if defined(DEBUG)
    iop->warning("Channel number: %i", depth);
    #endif
    set_info(stat.getDataWidth(), stat.getDataHeight(), depth);
    info_.channels(mask);
}
Пример #5
0
// the bit that does all the work
OP_ERROR SOP_rmanPtc::cookMySop(OP_Context &context)
{
    // get some useful bits & bobs
    UT_Interrupt *boss;
    float now = context.myTime;
    UT_String ptcFile = getPtcFile(now);
    int loadPercentage = getLoadPercentage(now);
    int displayPercentage = getDisplayPercentage(now);
    float pointSize = getPointSize(now);
    int useDisk = getUseDisk(now);
    int boundOnLoad = getBoundOnLoad(now);
    int displayChannel = getDisplayChannel(now);
    int onlyOutputDisplayChannel = getOnlyOutputDisplayChannel(now);
    /*
      float nearDensity = getNearDensity(now);
      float farDensity = getFarDensity(now);
      UT_String cullCamera = getCullCamera(now);
    */

    // lock out inputs
    if ( lockInputs(context) >= UT_ERROR_ABORT)
        error();

    // Check to see that there hasn't been a critical error in cooking the SOP.
    if (error() < UT_ERROR_ABORT)
    {
        boss = UTgetInterrupt();

        // here we make sure our detail is an instance of rmanPtcDetail
        rmanPtcDetail *ptc_gdp = dynamic_cast<rmanPtcSop::rmanPtcDetail *>(gdp);
        if ( !ptc_gdp )
            ptc_gdp = allocateNewDetail();

        // clear our gdp
        ptc_gdp->clearAndDestroy();

        // start our work
        boss->opStart("Loading point cloud");

        // get our bbox
        bool has_bbox = false;
        const GU_Detail *input_geo = inputGeo( 0, context );
        updateBBox( input_geo );

        // pass information to our detail
        ptc_gdp->point_size = pointSize;
        ptc_gdp->use_disk = useDisk;
        ptc_gdp->cull_bbox = mBBox;
        ptc_gdp->use_cull_bbox = (mHasBBox&&(!mBoundOnLoad))?true:false;
        ptc_gdp->display_probability = displayPercentage/100.f;
        ptc_gdp->display_channel = displayChannel;
        if ( onlyOutputDisplayChannel )
            ptc_gdp->display_channel = 0;

        // here we load our ptc
        if ( mReload )
        {            
            // clear everything
            mChannelNames.clear();
            cachePoints.clear();
            cacheNormals.clear();
            cacheRadius.clear();
            cacheData.clear();
            mRedraw = true;
            
            // open the point cloud
            PtcPointCloud ptc = PtcSafeOpenPointCloudFile(
                    const_cast<char*>(ptcFile.buffer()) );
            if ( !ptc )
            {
                UT_String msg( "Unable to open input file: " );
                msg += ptcFile;
                addError( SOP_MESSAGE, msg);
                boss->opEnd();
                return error();
            }

            // get some information from the ptc
            ptc_gdp->path = std::string(ptcFile.fileName());
            char **vartypes, **varnames;
            PtcGetPointCloudInfo( ptc, const_cast<char*>("npoints"),
                    &ptc_gdp->nPoints );
            PtcGetPointCloudInfo( ptc, const_cast<char*>("npointvars"),
                    &ptc_gdp->nChannels );
            PtcGetPointCloudInfo( ptc, const_cast<char*>("pointvartypes"),
                    &vartypes );
            PtcGetPointCloudInfo( ptc, const_cast<char*>("pointvarnames"),
                    &varnames );
            PtcGetPointCloudInfo( ptc, const_cast<char*>("datasize"),
                    &ptc_gdp->datasize );
            PtcGetPointCloudInfo( ptc, const_cast<char*>("bbox"),
                    ptc_gdp->bbox );

            // process our channel names
            ptc_gdp->types.clear();
            ptc_gdp->names.clear();
            for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i )
            {
                ptc_gdp->types.push_back( std::string(vartypes[i]) );
                ptc_gdp->names.push_back( std::string(varnames[i]) );
                std::string name = ptc_gdp->types[i] + " " + ptc_gdp->names[i];
                mChannelNames.push_back( name );
            }

            // what percentage of points should we load?
            float load_probability = loadPercentage/100.f;

            // load points into memory
            float point[3], normal[3];
            float radius;
            float data[ptc_gdp->datasize];
            srand(0);
            for ( unsigned int i=0; i<ptc_gdp->nPoints; ++i )
            {
                PtcReadDataPoint( ptc, point, normal, &radius, data );

                // bound on load
                if ( boundOnLoad )
                {
                    UT_Vector3 pt( point[0], point[1], point[2] );
                    if ( !mBBox.isInside(pt) )
                        continue;
                }

                // discard a percentage of our points
                if ( rand()/(float)RAND_MAX>load_probability )
                    continue;

                // put points into our cache
                cachePoints.push_back( point );
                cacheNormals.push_back( normal );
                cacheRadius.push_back( radius );
                for ( unsigned int j=0; j<ptc_gdp->datasize; ++j )
                    cacheData.push_back( data[j] );

                // break for the interrupt handler (i.e. press ESC)
                if ( boss->opInterrupt() )
                    break;
            }
            ptc_gdp->nLoaded = cachePoints.size();

            // mark our detail as valid and close our ptc
            PtcClosePointCloudFile( ptc );
            mReload = false;

            // force update on channel parameter
            getParm("chan").revertToDefaults(now);
        }

        // build a new primitive
        GU_PrimParticle::build( ptc_gdp, cachePoints.size(), 0 );

        // create our output geometry using the output % parameter
        // this is the same variable as GR_ uses to preview
        std::vector<UT_Vector3>::const_iterator pos_it = cachePoints.begin();
        std::vector<UT_Vector3>::const_iterator norm_it = cacheNormals.begin();
        std::vector<float>::const_iterator rad_it = cacheRadius.begin();
        std::vector<float>::const_iterator data_it = cacheData.begin();

        // add some standard attributes
        GB_AttributeRef n_attrib = ptc_gdp->addPointAttrib( "N", sizeof(UT_Vector3),
                GB_ATTRIB_VECTOR, 0 );
        GB_AttributeRef r_attrib = ptc_gdp->addPointAttrib( "radius", sizeof(float),
                GB_ATTRIB_FLOAT, 0 );
        ptc_gdp->N_attrib = n_attrib;
        ptc_gdp->R_attrib = r_attrib;

        // process the rest of our data attributes
        std::vector<GB_AttribType> data_types;
        std::vector<GB_AttributeRef> data_attribs;
        std::vector<int> data_size, data_offset;
        int offset_total = 0;
        ptc_gdp->attributes.clear();
        ptc_gdp->attribute_size.clear();
        for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i )
        {
            GB_AttribType type = GB_ATTRIB_FLOAT; // float, vector
            int size = 1;
            if ( ptc_gdp->types[i] == "point" ||
                    ptc_gdp->types[i] == "vector" ||
                    ptc_gdp->types[i] == "normal" )
            {
                type = GB_ATTRIB_VECTOR;
                size = 3;
            }
            if ( ptc_gdp->types[i] == "color" )
            {
                size=3;
            }
            if ( ptc_gdp->types[i] == "matrix" )
            {
                size=16;
            }
            offset_total += size;

            data_types.push_back( type );
            data_size.push_back( size );
            data_offset.push_back( offset_total );

            if ( onlyOutputDisplayChannel )
            {
                if ( displayChannel==i )
                {
                    GB_AttributeRef attrib = ptc_gdp->addPointAttrib(
                            ptc_gdp->names[i].c_str(), sizeof(float)*size,
                            type, 0 );
                    ptc_gdp->attributes.push_back( attrib );
                    ptc_gdp->attribute_size.push_back( size );
                    data_attribs.push_back( attrib );
                }
            }
            else
            {
                GB_AttributeRef attrib = ptc_gdp->addPointAttrib( ptc_gdp->names[i].c_str(),
                        sizeof(float)*size, type, 0 );
                ptc_gdp->attributes.push_back( attrib );
                ptc_gdp->attribute_size.push_back( size );
                data_attribs.push_back( attrib );
            }
        }
        cacheDataOffsets = data_offset;

/*
        // cull camera
        bool use_cull_cam = false;
        UT_Vector3 cam_pos(0,0,0);
        float cam_near=0.0, cam_far=0.0;

        if ( cullCamera!="" )
        {
            OBJ_Node *cam_node = OPgetDirector()->findOBJNode( cullCamera );
            if ( cam_node )
            {
                OBJ_Camera *cam = cam_node->castToOBJCamera();
                if ( cam )
                {
                    UT_DMatrix4 mtx;
                    cam->getWorldTransform( mtx, context );
                    std::cerr << "mtx: " << mtx << std::endl;
                    cam_pos *= mtx;
                    std::cerr << "pos: " << cam_pos << std::endl;
                    use_cull_cam = true;
                    cam_near = cam->getNEAR(now);
                    cam_far = cam->getFAR(now);
                    std::cerr << "near: " << cam_near << std::endl;
                    std::cerr << "far: " << cam_far << std::endl;

                    mRedraw = true;
                }
            }
            std::cerr << "cull camera: " << cullCamera << std::endl;
            std::cerr << nearDensity << ", " << farDensity << std::endl;
        }
*/
        // add data from our cached points to geometry
        // based on display/output probability
        srand(0);
        float density_mult = 1.f;
        while( pos_it!=cachePoints.end() )
        {

/*            
            if ( use_cull_cam )
            {
                float dist = ((*pos_it)-cam_pos).length();
                if ( dist<cam_near )
                    density_mult = nearDensity;
                else if ( dist>cam_far )
                    density_mult = farDensity;
                else
                {
                    float normalize_dist =( dist - cam_near ) / ( cam_far - cam_near );
                    density_mult = 1.f - normalize_dist;
                }
            }
*/

            if ( rand()/(float)RAND_MAX <
                    ptc_gdp->display_probability*density_mult )
            {
                if ( (!ptc_gdp->use_cull_bbox) ||
                        (ptc_gdp->use_cull_bbox &&
                                ptc_gdp->cull_bbox.isInside( *pos_it ) ) )
                {
                    // add to our SOP geometry
                    GEO_Point *pt = ptc_gdp->appendPoint();
                    pt->setPos( *pos_it );
                    (*pt->castAttribData<UT_Vector3>(n_attrib)) = *norm_it;
                    (*pt->castAttribData<float>(r_attrib)) = *rad_it;
                    const float *data = &*data_it;
                    for ( unsigned int i=0; i<data_types.size(); ++i )
                    {
                        if ( onlyOutputDisplayChannel )
                        {
                            if ( i==displayChannel )
                            {
                                pt->set( data_attribs[0], data, data_size[i] );
                            }
                            data += data_size[i];
                        }
                        else
                        {
                            pt->set( data_attribs[i], data, data_size[i] );
                            data += data_size[i];
                        }
                    }
                }
            }

            // increment our interators
            pos_it++;
            norm_it++;
            rad_it++;
            data_it+=ptc_gdp->datasize;
        }

        // delete our particle primitive
        ptc_gdp->deletePrimitive(0,0);
        
        // info in sop's message area
        std::stringstream ss;
        ss << "Name: " << ptc_gdp->path << std::endl;
        ss << "Points: " << ptc_gdp->nPoints << " - [ " <<
                ptc_gdp->nLoaded << " loaded ]" << std::endl;
        ss << "Channels: " << ptc_gdp->nChannels << std::endl;
        for ( unsigned int i=0; i<ptc_gdp->nChannels; ++i )
            ss << "  " << i << ": " << mChannelNames[i] << std::endl;
        addMessage( SOP_MESSAGE, ss.str().c_str() );

        // Tell the interrupt server that we've completed
        boss->opEnd();

        // force update?
        ptc_gdp->redraw = mRedraw;
        mRedraw = false;
    }

    // tidy up & go home
    unlockInputs();
    return error();
}
Пример #6
0
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() );
					}
				}
			}
		}
	}
}
Пример #7
0
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);
};
Пример #8
0
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);
        }
};