Пример #1
0
AtNode *convert( const IECore::ExternalProcedural *procedural )
{
	std::string nodeType = "procedural";
	// Allow a parameter "ai:nodeType" == "volume" to create a volume shape rather
	// than a procedural shape. Volume shapes provide "dso", "min" and "max" parameters
	// just as procedural shapes do, so the mapping is a fairly natural one.
	const CompoundDataMap &parameters = procedural->parameters()->readable();
	CompoundDataMap::const_iterator nodeTypeIt = parameters.find( "ai:nodeType" );
	if( nodeTypeIt != parameters.end() && nodeTypeIt->second->isInstanceOf( StringData::staticTypeId() ) )
	{
		nodeType = static_cast<const StringData *>( nodeTypeIt->second.get() )->readable();
	}
	AtNode *node = AiNode( nodeType.c_str() );

	AiNodeSetStr( node, "dso", procedural->getFileName().c_str() );
	ParameterAlgo::setParameters( node, parameters );

	const Box3f bound = procedural->bound();
	if( bound != Renderer::Procedural::noBound )
	{
		AiNodeSetPnt( node, "min", bound.min.x, bound.min.y, bound.min.z );
		AiNodeSetPnt( node, "max", bound.max.x, bound.max.y, bound.max.z );
	}
	else
	{
		// No bound available - expand procedural immediately.
		AiNodeSetBool( node, "load_at_init", true );
	}

	return node;
}
Пример #2
0
int main(int argc, char **argv)
{
    if (argc < 2)
    {
        usage();
        return 1;
    }
    
    std::ostringstream buffer;
    
    if (argc > 2)
    {
        for (int i = 2; i < argc; ++i)
        {
            buffer << argv[i] << " ";
        }
    }
    
    
    AiBegin();
    
    AiMsgSetConsoleFlags(AI_LOG_WARNINGS );//| AI_LOG_BACKTRACE);
    
    AtNode* procedural = AiNode("procedural");
    AiNodeSetStr(procedural, "name", "testbed");
    AiNodeSetStr(procedural, "dso", argv[1]);
    AiNodeSetStr(procedural, "data", buffer.str().c_str());
    AiNodeSetInt(procedural, "visibility", AI_RAY_CAMERA);
    
    AiASSWrite("/dev/stdout", AI_NODE_ALL, true);
    
    
    AiEnd();
    
    
}
AtNode * ProcessPointsBase(
        IPoints & prim, ProcArgs & args,
        SampleTimeSet & sampleTimes,
        std::vector<AtPoint> & vidxs,
		std::vector<float> & radius,
		MatrixSampleMap * xformSamples )
{
    if ( !prim.valid() )
    {
        return NULL;
    }
    
    Alembic::AbcGeom::IPointsSchema  &ps = prim.getSchema();
    TimeSamplingPtr ts = ps.getTimeSampling();
    
	sampleTimes.insert( ts->getFloorIndex(args.frame / args.fps, ps.getNumSamples()).second );
    
    std::string name = args.nameprefix + prim.getFullName();
    
    AtNode * instanceNode = NULL;
    
    std::string cacheId;
    
    SampleTimeSet singleSampleTimes;
    singleSampleTimes.insert( ts->getFloorIndex(args.frame / args.fps, ps.getNumSamples()).second );

	ICompoundProperty arbGeomParams = ps.getArbGeomParams();
	ISampleSelector frameSelector( *singleSampleTimes.begin() );
	std::vector<std::string> tags;

	//get tags
	if ( arbGeomParams != NULL && arbGeomParams.valid() )
	{
		if (arbGeomParams.getPropertyHeader("mtoa_constant_tags") != NULL)
		{
			const PropertyHeader * tagsHeader = arbGeomParams.getPropertyHeader("mtoa_constant_tags");
			if (IStringGeomParam::matches( *tagsHeader ))
			{
				IStringGeomParam param( arbGeomParams,  "mtoa_constant_tags" );
				if ( param.valid() )
				{
					IStringGeomParam::prop_type::sample_ptr_type valueSample =
									param.getExpandedValue( frameSelector ).getVals();

					if ( param.getScope() == kConstantScope || param.getScope() == kUnknownScope)
					{
						Json::Value jtags;
						Json::Reader reader;
						if(reader.parse(valueSample->get()[0], jtags))
							for( Json::ValueIterator itr = jtags.begin() ; itr != jtags.end() ; itr++ )
							{
								tags.push_back(jtags[itr.key().asUInt()].asString());
							}
					}
				}
			}
		}
	}

    if ( args.makeInstance )
    {
        std::ostringstream buffer;
        AbcA::ArraySampleKey sampleKey;
        
        
        for ( SampleTimeSet::iterator I = sampleTimes.begin();
                I != sampleTimes.end(); ++I )
        {
            ISampleSelector sampleSelector( *I );
            ps.getPositionsProperty().getKey(sampleKey, sampleSelector);
            
            buffer << GetRelativeSampleTime( args, (*I) ) << ":";
            sampleKey.digest.print(buffer);
            buffer << ":";
        }
        
        cacheId = buffer.str();
        
        instanceNode = AiNode( "ginstance" );
        AiNodeSetStr( instanceNode, "name", name.c_str() );
		args.createdNodes.push_back(instanceNode);

        if ( args.proceduralNode )
        {
            AiNodeSetByte( instanceNode, "visibility",
                    AiNodeGetByte( args.proceduralNode, "visibility" ) );
        
        }
        else
        {
            AiNodeSetByte( instanceNode, "visibility", AI_RAY_ALL );
        }

		ApplyTransformation( instanceNode, xformSamples, args );

		NodeCache::iterator I = g_meshCache.find(cacheId);

		// parameters overrides
		if(args.linkOverride)
			ApplyOverrides(name, instanceNode, tags, args);

		// shader assignation
		if (nodeHasParameter( instanceNode, "shader" ) )
		{
			if(args.linkShader)
			{
				ApplyShaders(name, instanceNode, tags, args);
			}
			else
			{
				AtArray* shaders = AiNodeGetArray(args.proceduralNode, "shader");
				if (shaders->nelements != 0)
				   AiNodeSetArray(instanceNode, "shader", AiArrayCopy(shaders));
			}
		}

        if ( I != g_meshCache.end() )
        {
            AiNodeSetPtr(instanceNode, "node", (*I).second );	
			return NULL;
        }
    }
    

    bool isFirstSample = true;

	float radiusPoint = 0.1f;
	if (AiNodeLookUpUserParameter(args.proceduralNode, "radiusPoint") !=NULL )
		radiusPoint = AiNodeGetFlt(args.proceduralNode, "radiusPoint");
	
	

	bool useVelocities = false;
	if ((sampleTimes.size() == 1) && (args.shutterOpen != args.shutterClose))
	{
		// no sample, and motion blur needed, let's try to get velocities.
		if(ps.getVelocitiesProperty().valid())
			useVelocities = true;
	}

	for ( SampleTimeSet::iterator I = sampleTimes.begin();
          I != sampleTimes.end(); ++I, isFirstSample = false)
    {
        ISampleSelector sampleSelector( *I );
        Alembic::AbcGeom::IPointsSchema::Sample sample = ps.getValue( sampleSelector );

		Alembic::Abc::P3fArraySamplePtr v3ptr = sample.getPositions();
		size_t pSize = sample.getPositions()->size(); 

		if(useVelocities && isFirstSample)
		{
			float scaleVelocity = 1.0f;
			if (AiNodeLookUpUserParameter(args.proceduralNode, "scaleVelocity") !=NULL )
				scaleVelocity = AiNodeGetFlt(args.proceduralNode, "scaleVelocity");

			vidxs.resize(pSize*2);
			Alembic::Abc::V3fArraySamplePtr velptr = sample.getVelocities();

			float timeoffset = ((args.frame / args.fps) - ts->getFloorIndex((*I), ps.getNumSamples()).second) * args.fps;

			for ( size_t pId = 0; pId < pSize; ++pId ) 
			{
				Alembic::Abc::V3f posAtOpen = ((*v3ptr)[pId] + (*velptr)[pId] * scaleVelocity *-timeoffset);			
				AtPoint pos1;
				pos1.x = posAtOpen.x;
				pos1.y = posAtOpen.y;
				pos1.z = posAtOpen.z;
				vidxs[pId]= pos1;

				Alembic::Abc::V3f posAtEnd = ((*v3ptr)[pId] + (*velptr)[pId]* scaleVelocity *(1.0f-timeoffset));
				AtPoint pos2;
				pos2.x = posAtEnd.x;
				pos2.y = posAtEnd.y;
				pos2.z = posAtEnd.z;
				vidxs[pId+pSize]= pos2;
				
				radius.push_back(radiusPoint);	
			}
		}
		else
			// not motion blur or correctly sampled particles
		{
			for ( size_t pId = 0; pId < pSize; ++pId ) 
			{
				AtPoint pos;
				pos.x = (*v3ptr)[pId].x;
				pos.y = (*v3ptr)[pId].y;
				pos.z = (*v3ptr)[pId].z;
				vidxs.push_back(pos);
				radius.push_back(radiusPoint);
			}
		}
	}
    
    AtNode* pointsNode = AiNode( "points" );
    
    if (!pointsNode)
    {
        AiMsgError("Failed to make points node for %s",
                prim.getFullName().c_str());
        return NULL;
    }
    

    args.createdNodes.push_back(pointsNode);
    if ( instanceNode != NULL)
    {
        AiNodeSetStr( pointsNode, "name", (name + ":src").c_str() );
    }
    else
    {
        AiNodeSetStr( pointsNode, "name", name.c_str() );
    }
    
    if(!useVelocities)
	{
		AiNodeSetArray(pointsNode, "points",
				AiArrayConvert( vidxs.size() / sampleTimes.size(), 
						sampleTimes.size(), AI_TYPE_POINT, (void*)(&(vidxs[0]))
								));
		AiNodeSetArray(pointsNode, "radius",
				AiArrayConvert( vidxs.size() / sampleTimes.size(), 
						sampleTimes.size(), AI_TYPE_FLOAT, (void*)(&(radius[0]))
								));

		if ( sampleTimes.size() > 1 )
		{
			std::vector<float> relativeSampleTimes;
			relativeSampleTimes.reserve( sampleTimes.size() );
        
			for (SampleTimeSet::const_iterator I = sampleTimes.begin();
					I != sampleTimes.end(); ++I )
			{
			   chrono_t sampleTime = GetRelativeSampleTime( args, (*I) );

				relativeSampleTimes.push_back(sampleTime);
                    
			}
        
			AiNodeSetArray( pointsNode, "deform_time_samples",
					AiArrayConvert(relativeSampleTimes.size(), 1,
							AI_TYPE_FLOAT, &relativeSampleTimes[0]));
		}
	}
	else
	{
		AiNodeSetArray(pointsNode, "points",
				AiArrayConvert( vidxs.size() / 2, 
						2, AI_TYPE_POINT, (void*)(&(vidxs[0]))
								));
		AiNodeSetArray(pointsNode, "radius",
				AiArrayConvert( vidxs.size() /2 / sampleTimes.size(), 
						sampleTimes.size(), AI_TYPE_FLOAT, (void*)(&(radius[0]))
								));		
		
		AiNodeSetArray( pointsNode, "deform_time_samples",
					AiArray(2, 1, AI_TYPE_FLOAT, 0.f, 1.f));

	}

   AddArbitraryGeomParams( arbGeomParams, frameSelector, pointsNode );
    
    if ( instanceNode == NULL )
	{
        if ( xformSamples )
        {
            ApplyTransformation( pointsNode, xformSamples, args );
        }
        
        return pointsNode;
	}
    else
    {
        AiNodeSetByte( pointsNode, "visibility", 0 );

		  AiNodeSetInt( pointsNode, "mode", 1 );
        
        AiNodeSetPtr(instanceNode, "node", pointsNode );
        g_meshCache[cacheId] = pointsNode;
        return pointsNode;
    }
    
}
Пример #4
0
AtNode * ProcessPolyMeshBase(
        primT & prim, ProcArgs & args,
        SampleTimeSet & sampleTimes,
        std::vector<AtUInt32> & vidxs,
        int subdiv_iterations,
        MatrixSampleMap * xformSamples, 
        const std::string & facesetName = "" )
{
    if ( !prim.valid() )
    {
        return NULL;
    }
    
    typename primT::schema_type  &ps = prim.getSchema();
    TimeSamplingPtr ts = ps.getTimeSampling();
    
    if ( ps.getTopologyVariance() != kHeterogenousTopology )
    {
        GetRelevantSampleTimes( args, ts, ps.getNumSamples(), sampleTimes );
    }
    else
    {
        sampleTimes.insert( args.frame / args.fps );
    }
    
    std::string name = args.nameprefix + prim.getFullName();
    
    AtNode * instanceNode = NULL;
    
    std::string cacheId;
    
    if ( args.makeInstance )
    {
        std::ostringstream buffer;
        AbcA::ArraySampleKey sampleKey;
        
        
        for ( SampleTimeSet::iterator I = sampleTimes.begin();
                I != sampleTimes.end(); ++I )
        {
            ISampleSelector sampleSelector( *I );
            ps.getPositionsProperty().getKey(sampleKey, sampleSelector);
            
            buffer << GetRelativeSampleTime( args, (*I) ) << ":";
            sampleKey.digest.print(buffer);
            buffer << ":";
        }
        
        buffer << "@" << subdiv_iterations;
        buffer << "@" << facesetName;
        
        cacheId = buffer.str();
        
        instanceNode = AiNode( "ginstance" );
        AiNodeSetStr( instanceNode, "name", name.c_str() );
        args.createdNodes.push_back(instanceNode);
        
        if ( args.proceduralNode )
        {
            AiNodeSetInt( instanceNode, "visibility",
                    AiNodeGetInt( args.proceduralNode, "visibility" ) );
        
        }
        else
        {
            AiNodeSetInt( instanceNode, "visibility", AI_RAY_ALL );
        }
        
        ApplyTransformation( instanceNode, xformSamples, args );
        
        
        NodeCache::iterator I = g_meshCache.find(cacheId);
        if ( I != g_meshCache.end() )
        {
            AiNodeSetPtr(instanceNode, "node", (*I).second );
            return NULL;
        }
        
    }
    
    
    
    SampleTimeSet singleSampleTimes;
    singleSampleTimes.insert( args.frame / args.fps );
    
    
    std::vector<AtByte> nsides;
    std::vector<float> vlist;
    
    std::vector<float> uvlist;
    std::vector<AtUInt32> uvidxs;
    
    
    // POTENTIAL OPTIMIZATIONS LEFT TO THE READER
    // 1) vlist needn't be copied if it's a single sample
    
    bool isFirstSample = true;
    for ( SampleTimeSet::iterator I = sampleTimes.begin();
          I != sampleTimes.end(); ++I, isFirstSample = false)
    {
        ISampleSelector sampleSelector( *I );
        typename primT::schema_type::Sample sample = ps.getValue( sampleSelector );
        
        if ( isFirstSample )
        {
            size_t numPolys = sample.getFaceCounts()->size();
            nsides.reserve( sample.getFaceCounts()->size() );
            for ( size_t i = 0; i < numPolys; ++i ) 
            {
                int32_t n = sample.getFaceCounts()->get()[i];
                
                if ( n > 255 )
                {
                    // TODO, warning about unsupported face
                    return NULL;
                }
                
                nsides.push_back( (AtByte) n );
            }
            
            size_t vidxSize = sample.getFaceIndices()->size();
            vidxs.reserve( vidxSize );
            vidxs.insert( vidxs.end(), sample.getFaceIndices()->get(),
                    sample.getFaceIndices()->get() + vidxSize );
        }
        
        
        vlist.reserve( vlist.size() + sample.getPositions()->size() * 3);
        vlist.insert( vlist.end(),
                (const float32_t*) sample.getPositions()->get(),
                ((const float32_t*) sample.getPositions()->get()) +
                        sample.getPositions()->size() * 3 );
    }
    
    ProcessIndexedBuiltinParam(
            ps.getUVsParam(),
            singleSampleTimes,
            uvlist,
            uvidxs,
            2);
    
    
    AtNode* meshNode = AiNode( "polymesh" );
    
    if (!meshNode)
    {
        AiMsgError("Failed to make polymesh node for %s",
                prim.getFullName().c_str());
        return NULL;
    }
    
    args.createdNodes.push_back(meshNode);
    
    if ( instanceNode != NULL)
    {
        AiNodeSetStr( meshNode, "name", (name + ":src").c_str() );
    }
    else
    {
        AiNodeSetStr( meshNode, "name", name.c_str() );
    }
    
    
    
    
    AiNodeSetArray(meshNode, "vidxs", 
            ArrayConvert(vidxs.size(), 1, AI_TYPE_UINT,
                    (void*)&vidxs[0]));
    
    AiNodeSetArray(meshNode, "nsides",
            ArrayConvert(nsides.size(), 1, AI_TYPE_BYTE,
                    &(nsides[0])));
    
    AiNodeSetArray(meshNode, "vlist",
            ArrayConvert( vlist.size() / sampleTimes.size(), 
                    sampleTimes.size(), AI_TYPE_FLOAT, (void*)(&(vlist[0]))));
    
    if ( !uvlist.empty() )
    {
        //TODO, option to disable v flipping
        for (size_t i = 1, e = uvlist.size(); i < e; i += 2)
        {
            uvlist[i] = 1.0 - uvlist[i];
        }
        
        AiNodeSetArray(meshNode, "uvlist",
            ArrayConvert( uvlist.size(), 1, AI_TYPE_FLOAT,
                (void*)(&(uvlist[0]))));
        
        if ( !uvidxs.empty() )
        {
            AiNodeSetArray(meshNode, "uvidxs",
                    ArrayConvert(uvidxs.size(), 1, AI_TYPE_UINT,
                            &(uvidxs[0])));
        }
        else
        {
            AiNodeSetArray(meshNode, "uvidxs",
                    ArrayConvert(vidxs.size(), 1, AI_TYPE_UINT,
                            &(vidxs[0])));
        }
    }
    
    if ( sampleTimes.size() > 1 )
    {
        std::vector<float> relativeSampleTimes;
        relativeSampleTimes.reserve( sampleTimes.size() );
        
        for (SampleTimeSet::const_iterator I = sampleTimes.begin();
                I != sampleTimes.end(); ++I )
        {
            relativeSampleTimes.push_back(
                    GetRelativeSampleTime( args, (*I) ) );
                    
        }
        
        AiNodeSetArray( meshNode, "deform_time_samples",
                ArrayConvert(relativeSampleTimes.size(), 1,
                        AI_TYPE_FLOAT, &relativeSampleTimes[0]));
    }
    
    // faceset visibility array
    if ( !facesetName.empty() )
    {
        if ( ps.hasFaceSet( facesetName ) )
        {
            ISampleSelector frameSelector( *singleSampleTimes.begin() );
            
            
            IFaceSet faceSet = ps.getFaceSet( facesetName );
            IFaceSetSchema::Sample faceSetSample = 
                    faceSet.getSchema().getValue( frameSelector );
            
            std::set<int> facesToKeep;
            
            
            facesToKeep.insert( faceSetSample.getFaces()->get(),
                    faceSetSample.getFaces()->get() +
                            faceSetSample.getFaces()->size() );
            
            bool *faceVisArray = new bool(nsides.size());
            
            for ( int i = 0; i < (int) nsides.size(); ++i )
            {
                faceVisArray[i] = facesToKeep.find( i ) != facesToKeep.end();
            }
            
            if ( AiNodeDeclare( meshNode, "face_visibility", "uniform BOOL" ) )
            {
                AiNodeSetArray( meshNode, "face_visibility",
                        ArrayConvert( nsides.size(), 1, AI_TYPE_BOOLEAN,
                                faceVisArray ) );
            }
            
            delete[] faceVisArray;
        }
    }
    
    {
        ICompoundProperty arbGeomParams = ps.getArbGeomParams();
        ISampleSelector frameSelector( *singleSampleTimes.begin() );
        
        AddArbitraryGeomParams( arbGeomParams, frameSelector, meshNode );
    }
    
    
    if ( instanceNode == NULL )
    {
        if ( xformSamples )
        {
            ApplyTransformation( meshNode, xformSamples, args );
        }
        
        return meshNode;
    }
    else
    {
        AiNodeSetInt( meshNode, "visibility", 0 );
        
        AiNodeSetPtr(instanceNode, "node", meshNode );
        g_meshCache[cacheId] = meshNode;
        return meshNode;
        
    }
    
}
Пример #5
0
AtNode *createInstanceNode(nodeData &nodata, userData * ud, int i)
{
  Alembic::AbcGeom::IPoints typedObject(ud->gIObjects[i].abc, Alembic::Abc::kWrapExisting);

  instanceCloudInfo * info = ud->gIObjects[i].instanceCloud;

  // check that we have the masternode
  size_t id = (size_t)ud->gIObjects[i].ID;
  size_t instanceID = (size_t)ud->gIObjects[i].instanceID;
  if(instanceID >= info->groupInfos.size())
  {
    AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceID  . Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id);
    return NULL;
  }
  size_t groupID = (size_t)ud->gIObjects[i].instanceGroupID;
  if(groupID >= info->groupInfos[instanceID].identifiers.size())
  {
    AiMsgError("[ExocortexAlembicArnold] Instance '%s.%d' has an invalid instanceGroupID. Aborting.",ud->gIObjects[i].abc.getFullName().c_str(),(int)id);
    return NULL;
  }

  instanceGroupInfo * group = &info->groupInfos[instanceID];

  // get the right centroidTime
  float centroidTime = ud->gCentroidTime;
  if(info->time.size() > 0)
  {
    centroidTime = info->time[0]->get()[id < info->time[0]->size() ? id : info->time[0]->size() - 1];
    if(info->time.size() > 1)
      centroidTime = (1.0f - info->timeAlpha) * centroidTime + info->timeAlpha * info->time[1]->get()[id < info->time[1]->size() ? id : info->time[1]->size() - 1];
    centroidTime = roundCentroid(centroidTime);
  }

  std::map<float,AtNode*>::iterator it = group->nodes[groupID].find(centroidTime);
  if(it == group->nodes[groupID].end())
  {
    AiMsgError("[ExocortexAlembicArnold] Cannot find masterNode '%s' for centroidTime '%f'. Aborting.",group->identifiers[groupID].c_str(),centroidTime);
    return NULL;
  }
  AtNode *usedMasterNode = it->second;

  AtNode *shapeNode = AiNode("ginstance");

  // setup name, id and the master node
  AiNodeSetStr(shapeNode, "name", getNameFromIdentifier(ud->gIObjects[i].abc.getFullName(),ud->gIObjects[i].ID,(long)groupID).c_str());
  AiNodeSetInt(shapeNode, "id", ud->gIObjects[i].instanceID); 
  AiNodeSetPtr(shapeNode, "node", usedMasterNode);

  // declare color on the ginstance
  if(info->color.size() > 0 && AiNodeDeclare(shapeNode, "Color", "constant RGBA"))
  {
    Alembic::Abc::C4f color = info->color[0]->get()[id < info->color[0]->size() ? id : info->color[0]->size() - 1];
    AiNodeSetRGBA(shapeNode, "Color", color.r, color.g, color.b, color.a);
  }

  // now let's take care of the transform
  AtArray * matrices = AiArrayAllocate(1,(AtInt)ud->gMbKeys.size(),AI_TYPE_MATRIX);
  for(size_t j=0;j<ud->gMbKeys.size(); ++j)
  {
    SampleInfo sampleInfo = getSampleInfo(
      ud->gMbKeys[j],
      typedObject.getSchema().getTimeSampling(),
      typedObject.getSchema().getNumSamples()
    );

    Alembic::Abc::M44f matrixAbc;
    matrixAbc.makeIdentity();
    const size_t floorIndex = j << 1;
    const size_t ceilIndex =  floorIndex + 1;

    // apply translation
    if(info->pos[floorIndex]->size() == info->pos[ceilIndex]->size())
    {
      matrixAbc.setTranslation(float(1.0 - sampleInfo.alpha) * info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + 
                               float(sampleInfo.alpha) * info->pos[ceilIndex]->get()[id < info->pos[ceilIndex]->size() ? id : info->pos[ceilIndex]->size() - 1]);
    }
    else
    {
      const float timeAlpha = getTimeOffsetFromObject( typedObject, sampleInfo );

      matrixAbc.setTranslation(info->pos[floorIndex]->get()[id < info->pos[floorIndex]->size() ? id : info->pos[floorIndex]->size() - 1] + 
                               info->vel[floorIndex]->get()[id < info->vel[floorIndex]->size() ? id : info->vel[floorIndex]->size() - 1] * timeAlpha);
    }

    // now take care of rotation
    if(info->rot.size() == ud->gMbKeys.size())
    {
      Alembic::Abc::Quatf rotAbc = info->rot[j]->get()[id < info->rot[j]->size() ? id : info->rot[j]->size() - 1];
      if(info->ang.size() == ud->gMbKeys.size() && sampleInfo.alpha > 0.0)
      {
        Alembic::Abc::Quatf angAbc = info->ang[j]->get()[id < info->ang[j]->size() ? id : info->ang[j]->size() -1] * (float)sampleInfo.alpha;
        if(angAbc.axis().length2() != 0.0f && angAbc.r != 0.0f)
        {
          rotAbc = angAbc * rotAbc;
          rotAbc.normalize();
        }
      }
      Alembic::Abc::M44f matrixAbcRot;
      matrixAbcRot.setAxisAngle(rotAbc.axis(),rotAbc.angle());
      matrixAbc = matrixAbcRot * matrixAbc;
    }

    // and finally scaling
    if(info->scale.size() == ud->gMbKeys.size() * 2)
    {
      const Alembic::Abc::V3f scalingAbc = info->scale[floorIndex]->get()[id < info->scale[floorIndex]->size() ? id : info->scale[floorIndex]->size() - 1] * 
                                           info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + 
                                           info->scale[ceilIndex]->get()[id < info->scale[ceilIndex]->size() ? id : info->scale[ceilIndex]->size() - 1] * 
                                           info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha);
      matrixAbc.scale(scalingAbc);
    }
    else
    {
      const float width = info->width[floorIndex]->get()[id < info->width[floorIndex]->size() ? id : info->width[floorIndex]->size() - 1] * float(1.0 - sampleInfo.alpha) + 
                          info->width[ceilIndex]->get()[id < info->width[ceilIndex]->size() ? id : info->width[ceilIndex]->size() - 1] * float(sampleInfo.alpha);
      matrixAbc.scale(Alembic::Abc::V3f(width,width,width));
    }

    // if we have offset matrices
    if(group->parents.size() > groupID && group->matrices.size() > groupID)
    {
      if(group->objects[groupID].valid() && group->parents[groupID].valid())
      {
        // we have a matrix map and a parent.
        // now we need to check if we already exported the matrices
        std::map<float,std::vector<Alembic::Abc::M44f> >::iterator it;
        std::vector<Alembic::Abc::M44f> offsets;
        it = group->matrices[groupID].find(centroidTime);
        if(it == group->matrices[groupID].end())
        {
          std::vector<float> samples(ud->gMbKeys.size());
          offsets.resize(ud->gMbKeys.size());
          for(AtInt sampleIndex=0;sampleIndex<(AtInt)ud->gMbKeys.size(); ++sampleIndex)
          {
            offsets[sampleIndex].makeIdentity();
            // centralize the time once more
            samples[sampleIndex] = centroidTime + ud->gMbKeys[sampleIndex] - ud->gCentroidTime;
          }

          // if the transform differs, we need to compute the offset matrices
          // get the parent, which should be a transform
          Alembic::Abc::IObject parent = group->parents[groupID];
          Alembic::Abc::IObject xform = group->objects[groupID].getParent();
          while(Alembic::AbcGeom::IXform::matches(xform.getMetaData()) && xform.getFullName() != parent.getFullName())
          {
            // cast to a xform
            Alembic::AbcGeom::IXform parentXform(xform,Alembic::Abc::kWrapExisting);
            if(parentXform.getSchema().getNumSamples() == 0)
              break;

            // loop over all samples
            for(size_t sampleIndex=0;sampleIndex<ud->gMbKeys.size(); ++sampleIndex)
            {
              SampleInfo sampleInfo = getSampleInfo(
                 samples[sampleIndex],
                 parentXform.getSchema().getTimeSampling(),
                 parentXform.getSchema().getNumSamples()
              );

              // get the data and blend it if necessary
              Alembic::AbcGeom::XformSample sample;
              parentXform.getSchema().get(sample,sampleInfo.floorIndex);
              Alembic::Abc::M44f abcMatrix;
              Alembic::Abc::M44d abcMatrixd = sample.getMatrix();
              for(int x=0;x<4;x++)
                 for(int y=0;y<4;y++)
                    abcMatrix[x][y] = (float)abcMatrixd[x][y];
               
              if(sampleInfo.alpha >= sampleTolerance)
              {
                parentXform.getSchema().get(sample,sampleInfo.ceilIndex);
                Alembic::Abc::M44d ceilAbcMatrixd = sample.getMatrix();
                Alembic::Abc::M44f ceilAbcMatrix;
                for(int x=0;x<4;x++)
                  for(int y=0;y<4;y++)
                     ceilAbcMatrix[x][y] = (float)ceilAbcMatrixd[x][y];
                abcMatrix = float(1.0 - sampleInfo.alpha) * abcMatrix + float(sampleInfo.alpha) * ceilAbcMatrix;
              }

              offsets[sampleIndex] = abcMatrix * offsets[sampleIndex];
            }

            // go upwards
            xform = xform.getParent();
          }
          group->matrices[groupID].insert(std::pair<float,std::vector<Alembic::Abc::M44f> >(centroidTime,offsets));
        }
        else
          offsets = it->second;

        // this means we have the right amount of matrices to blend against
        if(offsets.size() > j)
          matrixAbc = offsets[j] * matrixAbc;
      }
    }

    // store it to the array
    AiArraySetMtx(matrices,(AtULong)j,matrixAbc.x);
  }

  AiNodeSetArray(shapeNode,"matrix",matrices);
  AiNodeSetBool(shapeNode, "inherit_xform", FALSE);

  return shapeNode;
}
Пример #6
0
AtNode *createCurvesNode(nodeData &nodata, userData * ud, std::vector<float> &samples, int i)
{
  Alembic::AbcGeom::ICurves typedObject(nodata.object, Alembic::Abc::kWrapExisting);
  size_t minNumSamples = typedObject.getSchema().getNumSamples() == 1 ? typedObject.getSchema().getNumSamples() : samples.size();

  shiftedProcessing(nodata, ud);

  AtNode *shapeNode = AiNode("curves");
  nodata.createdShifted = false;

  // create arrays to hold the data
  AtArray *pos = NULL;

  // loop over all samples
  AtULong posOffset = 0;
  size_t totalNumPoints =  0;
  size_t totalNumPositions = 0;
  for(size_t sampleIndex = 0; sampleIndex < minNumSamples; ++sampleIndex)
  {
    SampleInfo sampleInfo = getSampleInfo(
      samples[sampleIndex],
      typedObject.getSchema().getTimeSampling(),
      typedObject.getSchema().getNumSamples()
    );

    // get the floor sample
    Alembic::AbcGeom::ICurvesSchema::Sample sample;
    typedObject.getSchema().get(sample,sampleInfo.floorIndex);

    // access the num points
    Alembic::Abc::Int32ArraySamplePtr abcNumPoints = sample.getCurvesNumVertices();

    // take care of the topology
    if(sampleIndex == 0)
    {
      // hard coded pixel width, basis and mode
      AiNodeSetFlt(shapeNode, "min_pixel_width", 0.25f);
      AiNodeSetStr(shapeNode, "basis", "catmull-rom");
      AiNodeSetStr(shapeNode, "mode", ud->gCurvesMode.c_str());

      // setup the num_points
      AtArray * numPoints = AiArrayAllocate((AtInt)abcNumPoints->size(),1,AI_TYPE_UINT);
      for(size_t i=0;i<abcNumPoints->size();i++)
      {
        totalNumPoints += abcNumPoints->get()[i];
        totalNumPositions += abcNumPoints->get()[i] + 2;
        AiArraySetUInt(numPoints,(AtULong)i,(AtUInt)(abcNumPoints->get()[i]+2));
      }
      AiNodeSetArray(shapeNode,"num_points",numPoints);

      // check if we have a radius
      Alembic::Abc::IFloatArrayProperty propRadius;
			if( getArbGeomParamPropertyAlembic( typedObject, "radius", propRadius ) )
      {
        Alembic::Abc::FloatArraySamplePtr abcRadius = propRadius.getValue(sampleInfo.floorIndex);

        AtArray * radius = AiArrayAllocate((AtInt)abcRadius->size(),1,AI_TYPE_FLOAT);
        for(size_t i=0; i < abcRadius->size(); ++i)
          AiArraySetFlt(radius,(AtULong)i,abcRadius->get()[i]);
        AiNodeSetArray(shapeNode,"radius",radius);
      }

      // check if we have uvs
      Alembic::AbcGeom::IV2fGeomParam uvsParam = typedObject.getSchema().getUVsParam();
      if(uvsParam.valid())
      {
        Alembic::Abc::V2fArraySamplePtr abcUvs = uvsParam.getExpandedValue(sampleInfo.floorIndex).getVals();
        if(AiNodeDeclare(shapeNode, "Texture_Projection", "uniform POINT2"))
        {
          AtArray* uvs = AiArrayAllocate((AtInt)abcUvs->size(), 1, AI_TYPE_POINT2);
          AtPoint2 uv;
          for(size_t i=0; i<abcUvs->size(); i++)
          {
            uv.x = abcUvs->get()[i].x;
            uv.y = abcUvs->get()[i].y;
            AiArraySetPnt2(uvs, (AtULong)i, uv);
          }
          AiNodeSetArray(shapeNode, "Texture_Projection", uvs);
        }
      }

      // check if we have colors
      Alembic::Abc::IC4fArrayProperty propColor;
			if( getArbGeomParamPropertyAlembic( typedObject, "color", propColor ) )
      {
        Alembic::Abc::C4fArraySamplePtr abcColors = propColor.getValue(sampleInfo.floorIndex);
        AtBoolean result = false;
        if(abcColors->size() == 1)
          result = AiNodeDeclare(shapeNode, "Color", "constant RGBA");
        else if(abcColors->size() == abcNumPoints->size())
          result = AiNodeDeclare(shapeNode, "Color", "uniform RGBA");
        else
          result = AiNodeDeclare(shapeNode, "Color", "varying RGBA");

        if(result)
        {
          AtArray * colors = AiArrayAllocate((AtInt)abcColors->size(), 1, AI_TYPE_RGBA);
          AtRGBA color;
          for(size_t i=0; i<abcColors->size(); ++i)
          {
            color.r = abcColors->get()[i].r;
            color.g = abcColors->get()[i].g;
            color.b = abcColors->get()[i].b;
            color.a = abcColors->get()[i].a;
            AiArraySetRGBA(colors, (AtULong)i, color);
          }
          AiNodeSetArray(shapeNode, "Color", colors);
        }
      }
    }

    // access the positions
    Alembic::Abc::P3fArraySamplePtr abcPos = sample.getPositions();
    if(pos == NULL)
      pos = AiArrayAllocate((AtInt)(totalNumPositions * 3),(AtInt)minNumSamples,AI_TYPE_FLOAT);

    // if we have to interpolate
    bool done = false;
    if(sampleInfo.alpha > sampleTolerance)
    {
      Alembic::AbcGeom::ICurvesSchema::Sample sample2;
      typedObject.getSchema().get(sample2,sampleInfo.ceilIndex);
      Alembic::Abc::P3fArraySamplePtr abcPos2 = sample2.getPositions();
      float alpha = (float)sampleInfo.alpha;
      float ialpha = 1.0f - alpha;
      size_t offset = 0;
      if(abcPos2->size() == abcPos->size())
      {
        for(size_t i=0; i<abcNumPoints->size(); ++i)
        {
          // add the first and last point manually (catmull clark)
          for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
          {
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha);
            if(j==0 || j == abcNumPoints->get()[i]-1)
            {
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x * ialpha + abcPos2->get()[offset].x * alpha);
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y * ialpha + abcPos2->get()[offset].y * alpha);
              AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z * ialpha + abcPos2->get()[offset].z * alpha);
            }
            ++offset;
          }
        }
        done = true;
      }
      else
      {
        Alembic::Abc::P3fArraySamplePtr abcVel = sample.getPositions();
        if(abcVel)
        {
          if(abcVel->size() == abcPos->size())
          {
            for(size_t i=0; i<abcNumPoints->size(); ++i)
            {
              // add the first and last point manually (catmull clark)
              for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
              {
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha);
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha);
                AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha);
                if(j==0 || j == abcNumPoints->get()[i]-1)
                {
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x + abcVel->get()[offset].x * alpha);
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y + abcVel->get()[offset].y * alpha);
                  AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z + abcVel->get()[offset].z * alpha);
                }
                ++offset;
              }
            }
            done = true;
          }
        }
      }
    }

    if(!done)
    {
      size_t offset = 0;
      for(size_t i=0; i<abcNumPoints->size(); ++i)
      {
        // add the first and last point manually (catmull clark)
        for(size_t j=0; j<abcNumPoints->get()[i]; ++j)
        {
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x);
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y);
          AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z);
          if(j==0 || j == abcNumPoints->get()[i]-1)
          {
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].x);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].y);
            AiArraySetFlt(pos,posOffset++,abcPos->get()[offset].z);
          }
          ++offset;
        }
      }
    }
  }

  AiNodeSetArray(shapeNode, "points", pos);
  return shapeNode;
}
Пример #7
0
static AtNode *MyGetNode(void *user_ptr, int i){

	cout << "BEGIN GET NODE" << endl;
	const McdMiddleData* params = static_cast<McdMiddleData*>(user_ptr);

	const char* g_assetsPath	= params->m_assetsPath;
	int g_agentID				= params->m_agentID;
	int g_ppID					= params->m_ppID;	
	int g_geoID					= params->m_geoID;	
	int g_poly0_subd1			= params->m_poly0_subd1;
	int g_motionBlur			= params->m_motionBlur;
	float g_motionShutter		= params->m_motionShutter; 
	const char* g_poseData		= params->m_poseData;	

	string agentFolder;
	string agentPath2,geoPath2,weightPath2;
	string currentLine;
	//long counter1;
	//long counter2;

#ifdef WIN32
	EnterCriticalSection(&g_cs1);
#else
	pthread_mutex_lock( &cs_mutex );
#endif

	if (!have_Data)
		initAssets(params);

#ifdef WIN32
	LeaveCriticalSection(&g_cs1);
#else
	pthread_mutex_unlock( &cs_mutex );
#endif


#ifdef MiarmyDebug
	ofstream logFile("e:/logFile.txt");
#endif

	// agent file:
	// /////////////////////////////////////////////////////////////////////////////
	// /////////////////////////////////////////////////////////////////////////////

	bool motionBlurDef = false;
	float motionShutter = 0.0f;
	if (g_motionBlur == 1) {
		motionBlurDef = true;
		motionShutter = g_motionShutter;
	}
	vector<float> poseDataRaw;
	vector<float> poseDataRawNext;

	McdUtils utils;
	utils.getPoseRawData(poseDataRaw,poseDataRawNext, motionBlurDef, g_poseData);

#ifdef MiarmyDebug
	logFile<<"pose data raw"<<endl;
	for (uint i = 0; i < poseDataRaw.size(); i++){
		logFile<<poseDataRaw[i]<<" ";
	}
#endif

	char tempBuf[10];
	string ppIdStr, agentTypeIdStr, geoTypeIdStr;
	string assetsFolder(g_assetsPath);
	sprintf(tempBuf, "%d", g_ppID);		ppIdStr			= tempBuf;
	sprintf(tempBuf, "%d", g_agentID);	agentTypeIdStr	= tempBuf;
	sprintf(tempBuf, "%d", g_geoID);	geoTypeIdStr	= tempBuf;

	string geomStr = "geom";
	geomStr = geomStr + ppIdStr;


	agentFolder =  agentFolderPre + agentTypeIdStr;

	//			d:/pp		   /	   McdAgentType0 /		 McdAgentMain.txt
	agentPath2= assetsFolder +  slash + agentFolder +  slash +  agentFile2;
	//		  d:/pp			 /		 McdAgentType0 /	   McdGeoFiles /		 McdGeo		  0	
	geoPath2= assetsFolder +  slash + agentFolder +  slash +  geoFolder +  slash +  geoFilePre + geoTypeIdStr;
	//		     d:/pp			/ 		McdAgentType0 /		  McdGeoFiles /		McdWeight			0
	weightPath2= assetsFolder +  slash + agentFolder +  slash +  geoFolder +  slash +  weightFilePre + geoTypeIdStr;

	// we already have agentPath2, geoPath2, and weightPath2, let's extract data:
	// get bone number and org pose 
	vector<McdMatrix> orgPoseMatrixList;
	vector<McdMatrix> currentPoseMatrixList;
	vector<McdMatrix> nextPoseMatrixList;
	int nbBone = (int)(agentFiles_Data[g_agentID][0] + .1f);

	utils.getPoseMatrices( orgPoseMatrixList,
						   currentPoseMatrixList,
					       nextPoseMatrixList,
					       agentFiles_Data,
					       poseDataRaw,
					       poseDataRawNext,
						   nbBone, g_agentID, motionBlurDef);

	// now get the weights 
	McdPointWeight weightList;
	int nbPoints = utils.getWeightsFromFile( weightList, weightPath2, weightFiles_Data, g_agentID, g_geoID );


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// session 3: get the data from geo file //////////////////////////////////////////////////////////////////////

	//bool startCollect = false;
	McdGeo geo;

	vector<float> currentPoints, nextPoints;	// modified from points;
	vector<float> currentNormals, nextNormals;	// modified from normals;

	utils.getGeoFromFile( geo, geoFiles_Data, currentNormals, nextNormals, g_geoID, g_agentID, motionBlurDef);

	// statistic final information:
	int nbNormalFromRib = geo.nidxs.size();

	if (geo.points.size() / 3 != nbPoints) return 0;
	
#ifdef MiarmyDebug
	logFile << "-----------> points number from pp exportor:  >>>>" <<nbPoints<<endl;
	logFile << "-----------> normals number from rib:  >>>>" <<nbNormalFromRib<<endl;
#endif
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// session 4: modify the data in vector ///////////////////////////////////////////////////////////////////////


	// modify points by skinning info
#ifdef MiarmyDebug
	logFile << "*************start to deal with points********************************************"<<endl;
#endif

	McdPoint currentPoint;
	McdPoint nextPoint;
	int nbWeights;
	int boneID; float weight;
	for (int i = 0; i < nbPoints; i++)
	{
		currentPoint.x = geo.points[i*3]; currentPoint.y = geo.points[i*3 + 1]; currentPoint.z = geo.points[i*3 + 2];
		if (motionBlurDef)
		{
			nextPoint = currentPoint;
		}

		nbWeights = weightList.nbWeights[i];
#ifdef MiarmyDebug
		logFile<<"-------------------------------"<<endl;
		logFile << "point pre info: "<<currentPoint.x<<"   "<<currentPoint.y<<"   "<<currentPoint.z<<"   "<<endl;
#endif

		McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out
		McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out
		for (int j = 0; j < nbWeights; j++)
		{
			boneID = weightList.pointIdList[i][j];
			weight = weightList.pointWeights[i][j];
			
#ifdef MiarmyDebug
			logFile <<"pointid: "<<i<<" boneId: "<<boneID<<" weight: "<<weight<<endl;
#endif 
			deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight;
			if (motionBlurDef)
			{
				deformMatNext = deformMatNext + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight;
			}

		}

		currentPoint = currentPoint * deformMat;
		if (motionBlurDef)
		{
			nextPoint = nextPoint * deformMatNext;
		}

		// put result to points:
		currentPoints.push_back(currentPoint.x); currentPoints.push_back(currentPoint.y); currentPoints.push_back(currentPoint.z);
		if (motionBlurDef)
		{
			nextPoints.push_back(nextPoint.x); nextPoints.push_back(nextPoint.y); nextPoints.push_back(nextPoint.z);
		}

#ifdef MiarmyDebug
		logFile << "result point info: "<<currentPoints[i*3]<<"   "<<currentPoints[i*3+1]<<"   "<<currentPoints[i*3+2]<<"   "<<endl;
		if (motionBlurDef)
			logFile << "next point info: "<<nextPoints[i*3]<<"   "<<nextPoints[i*3+1]<<"   "<<nextPoints[i*3+2]<<"   "<<endl;
#endif
	}

	// modify normal by skinning info
	McdVector currentNormal, nextNormal;
	int normalPointID, normalID;
	for (int i = 0; i < nbNormalFromRib; i++){
		normalID = geo.nidxs[i];

		currentNormal.x = geo.normals[normalID*3]; currentNormal.y = geo.normals[normalID*3+1]; currentNormal.z = geo.normals[normalID*3+2];
		if (motionBlurDef){
			nextNormal.x = geo.normals[normalID*3]; nextNormal.y = geo.normals[normalID*3+1]; nextNormal.z = geo.normals[normalID*3+2];
		}

		normalPointID = geo.vidxs[i];

		nbWeights = weightList.nbWeights[normalPointID];
#ifdef MiarmyDebug
		logFile << "point normal info: "<<currentNormal.x<<"   "<<currentNormal.y<<"   "<<currentNormal.z<<"   "<<endl;

		if (motionBlurDef){
			logFile << "next point normal info: "<<nextNormal.x<<"   "<<nextNormal.y<<"   "<<nextNormal.z<<"   "<<endl;
		}
#endif

		McdMatrix deformMat; deformMat = deformMat * 0.0f; // zero out
		McdMatrix deformMatNext; deformMatNext = deformMatNext * 0.0f; // zero out
		for (int j = 0; j < nbWeights; j++){
			
			boneID = weightList.pointIdList[normalPointID][j];
			weight = weightList.pointWeights[normalPointID][j];

			deformMat = deformMat + (orgPoseMatrixList[boneID] * currentPoseMatrixList[boneID]) * weight;
			if (motionBlurDef){
				deformMat = deformMat + (orgPoseMatrixList[boneID] * nextPoseMatrixList[boneID]) * weight;
			}

		}

		currentNormal = currentNormal * deformMat;
		currentNormal.normalize();
		if (motionBlurDef){
			nextNormal = nextNormal * deformMatNext;
			nextNormal.normalize();
		}

		// put result to normals:
		currentNormals[normalID*3] = currentNormal.x; currentNormals[normalID*3+1] = currentNormal.y; currentNormals[normalID*3+2] = currentNormal.z; 
		if (motionBlurDef){
			nextNormals[normalID*3] = nextNormal.x; nextNormals[normalID*3+1] = nextNormal.y; nextNormals[normalID*3+2] = nextNormal.z; 
		}

#ifdef MiarmyDebug
		logFile << "result normal info: "<<currentNormals[normalID*3]<<"   "<<currentNormals[normalID*3+1]<<"   "<<currentNormals[normalID*3+2]<<"   "<<endl;
		if (motionBlurDef)
			logFile << "result next normal info: "<<nextNormals[normalID*3]<<"   "<<nextNormals[normalID*3+1]<<"   "<<nextNormals[normalID*3+2]<<"   "<<endl;
#endif
	}

#ifdef MiarmyDebug
	logFile <<endl<< "----------------------- END -----------------------: ";
	logFile.close();
#endif

	AtArray *nsidesArray;
	AtArray *vidxsArray;
	AtArray *nidxsArray;
	AtArray *uvidxsArray;
	AtArray *vlistArray;
	AtArray *nlistArray;
	AtArray *uvlistArray;

	// proc geo: 
	if (!motionBlurDef){
		nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT);
		vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT);
		nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT);
		uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT);
		vlistArray = AiArrayAllocate(geo.points.size() / 3, 1, AI_TYPE_POINT);
		nlistArray = AiArrayAllocate(geo.normals.size() / 3, 1, AI_TYPE_VECTOR);
		uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2);

		uint i;
		AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2;
		uint nbPnts = currentPoints.size() / 3;
		uint nbNormals = currentNormals.size() / 3;
		uint nbUVs = geo.uvlist.size() / 2;
		for (i = 0; i < geo.nsides.size(); i++)
			AiArraySetUInt(nsidesArray, i, geo.nsides[i]);
		for (i = 0; i < geo.vidxs.size(); i++)
			AiArraySetUInt(vidxsArray, i, geo.vidxs[i]);
		for (i = 0; i < geo.nidxs.size(); i++)
			AiArraySetUInt(nidxsArray, i, geo.nidxs[i]);
		for (i = 0; i < geo.uvidxs.size(); i++)
			AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]);
		for (i = 0; i < nbPnts; i++){
			tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2];
			AiArraySetPnt(vlistArray, i, tempPoint);
		}
		for (i = 0; i < nbNormals; i++){
			tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2];
			AiArraySetPnt(nlistArray, i, tempNormal);
		}
		for (i = 0; i < nbUVs; i++){
			tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1];
			AiArraySetPnt2(uvlistArray, i, tempPoint2);
		}


	} else {
		nsidesArray = AiArrayAllocate(geo.nsides.size(), 1, AI_TYPE_UINT);
		vidxsArray = AiArrayAllocate(geo.vidxs.size(), 1, AI_TYPE_UINT);
		nidxsArray = AiArrayAllocate(geo.nidxs.size(), 1, AI_TYPE_UINT);
		uvidxsArray = AiArrayAllocate(geo.uvidxs.size(), 1, AI_TYPE_UINT);
		vlistArray = AiArrayAllocate(geo.points.size() / 3, 2, AI_TYPE_POINT);
		nlistArray = AiArrayAllocate(geo.normals.size() / 3, 2, AI_TYPE_VECTOR);
		uvlistArray = AiArrayAllocate(geo.uvlist.size() / 2, 1, AI_TYPE_POINT2);

		uint i;
		AtPoint tempPoint; AtVector tempNormal; AtPoint2 tempPoint2;
		uint nbPnts = currentPoints.size() / 3;
		uint nbNormals = currentNormals.size() / 3;
		uint nbUVs = geo.uvlist.size() / 2;
		for (i = 0; i < geo.nsides.size(); i++)
			AiArraySetUInt(nsidesArray, i, geo.nsides[i]);
		for (i = 0; i < geo.vidxs.size(); i++)
			AiArraySetUInt(vidxsArray, i, geo.vidxs[i]);
		for (i = 0; i < geo.nidxs.size(); i++)
			AiArraySetUInt(nidxsArray, i, geo.nidxs[i]);
		for (i = 0; i < geo.uvidxs.size(); i++)
			AiArraySetUInt(uvidxsArray, i, geo.uvidxs[i]);
		for (i = 0; i < nbPnts; i++){
			tempPoint.x = currentPoints[i*3]; tempPoint.y = currentPoints[i*3+1]; tempPoint.z = currentPoints[i*3+2];
			AiArraySetPnt(vlistArray, i, tempPoint);
		}
		for (i = 0; i < nbNormals; i++){
			tempNormal.x = currentNormals[i*3]; tempNormal.y = currentNormals[i*3+1]; tempNormal.z = currentNormals[i*3+2];
			AiArraySetPnt(nlistArray, i, tempNormal);
		}
		for (i = 0; i < nbPnts; i++){
			tempPoint.x = nextPoints[i*3]; tempPoint.y = nextPoints[i*3+1]; tempPoint.z = nextPoints[i*3+2];
			AiArraySetPnt(vlistArray, i+nbPnts, tempPoint);
		}
		for (i = 0; i < nbNormals; i++){
			tempNormal.x = nextNormals[i*3]; tempNormal.y = nextNormals[i*3+1]; tempNormal.z = nextNormals[i*3+2];
			AiArraySetPnt(nlistArray, i+nbNormals, tempNormal);
		}
		for (i = 0; i < nbUVs; i++){
			tempPoint2.x = geo.uvlist[i*2]; tempPoint2.y = geo.uvlist[i*2+1];
			AiArraySetPnt2(uvlistArray, i, tempPoint2);
		}
	}

	AtNode *meshNode = AiNode("polymesh");
	AiNodeSetStr(meshNode, "name", geomStr.c_str());
	AiNodeSetArray(meshNode, "nsides", nsidesArray);
	AiNodeSetArray(meshNode, "vidxs", vidxsArray);
	if (g_poly0_subd1 != 1)
		AiNodeSetArray(meshNode, "nidxs", nidxsArray);
	AiNodeSetArray(meshNode, "uvidxs", uvidxsArray);
	AiNodeSetArray(meshNode, "vlist", vlistArray);
	if (g_poly0_subd1 != 1)
		AiNodeSetArray(meshNode, "nlist", nlistArray);
	AiNodeSetArray(meshNode, "uvlist", uvlistArray);
	AiNodeSetBool(meshNode, "smoothing", true);

	if (g_poly0_subd1 == 1)
		AiNodeSetStr(meshNode, "subdiv_type", "catclark");


	lockup = false;
	cout << "END GET NODE" << endl;
	return meshNode;
}