INode* PatchDeformPW::GetNodeFromModContext(LocalPatchData *smd)
	{

	int	i;

    PatchEnumProc dep;              
	DoEnumDependents(&dep);
	for ( i = 0; i < dep.Nodes.Count(); i++)
		{
		INode *node = dep.Nodes[i];
		BOOL found = FALSE;

		if (node)
			{
			Object* obj = node->GetObjectRef();
	
			if ( RecursePipeAndMatch(smd,obj) )
				{
				return node;
				}
// look at the SkinWrapMesh.cpp code here....
			}
		}
	return NULL;
	}
void PatchDeformPW::SetResampleModContext(BOOL resample)
{
    PatchEnumProc dep;              
	DoEnumDependents(&dep);
	for ( int i = 0; i < dep.Nodes.Count(); i++)
		{
		INode *node = dep.Nodes[i];
		BOOL found = FALSE;

		if (node)
			{
			Object* obj = node->GetObjectRef();
	
			 RecursePipeAndMatch2(this,obj,resample) ;
			}
		}
}
Beispiel #3
0
void BlobMesh::BuildMesh(TimeValue t)
{

	//TODO: Implement the code to build the mesh representation of the object
	//    using its parameter settings at the time passed. The plug-in should 
	//    use the data member mesh to store the built mesh.
	int numberOfNodes = pblock2->Count(pb_nodelist);

	float size, tension, renderCoarseness, viewCoarseness,coarseness;

	// Interval valid;
	pblock2->GetValue(pb_size,t,size,ivalid);
	pblock2->GetValue(pb_tension,t,tension,ivalid);
	if (tension < 0.011f) tension = 0.011f;
	if (tension > 1.0f) tension = 1.0f;

	pblock2->GetValue(pb_render,t,renderCoarseness,ivalid);
	pblock2->GetValue(pb_viewport,t,viewCoarseness,ivalid);

	BOOL autoCoarseness;
	pblock2->GetValue(pb_relativecoarseness,t,autoCoarseness,ivalid);

	BOOL largeDataSetOpt;
	pblock2->GetValue(pb_oldmetaballmethod,t,largeDataSetOpt,ivalid);


	BOOL useSoftSel;
	float minSize;
	pblock2->GetValue(pb_usesoftsel,t,useSoftSel,ivalid);
	pblock2->GetValue(pb_minsize,t,minSize,ivalid);

	if (inRender)
		coarseness = renderCoarseness;
	else coarseness = viewCoarseness;

	if (autoCoarseness)
		coarseness = size/coarseness;

	Tab<INode *> pfList;

	BOOL useAllPFEvents;
	pblock2->GetValue(pb_useallpf,0,useAllPFEvents,FOREVER);



	int pfCt = pblock2->Count(pb_pfeventlist);

	BOOL offInView;
	pblock2->GetValue(pb_offinview,0,offInView,FOREVER);



	for (int i = 0; i < pfCt; i++)
	{
		INode* node = NULL;
		pblock2->GetValue(pb_pfeventlist,0,node,FOREVER,i);
		if (node)
			pfList.Append(1,&node);
	}

	float thres = 0.6f;

	//need to get our tm
	if (selfNode == NULL)
	{
		MyEnumProc dep(true);
		DoEnumDependents(&dep);
		if (dep.Nodes.Count() > 0)
			selfNode = dep.Nodes[0];
	}

	Matrix3 baseTM(1);

	if (selfNode != NULL)
		baseTM = Inverse(selfNode->GetObjectTM(t));
	//loop throght the nodes

	if (!inRender)
	{
		if (offInView)
			numberOfNodes = 0;

	}

	std::vector<SphereData> data;
	data.reserve(500);

	for (int i = 0; i < numberOfNodes; i++)
	{
		INode* node = NULL;
		pblock2->GetValue(pb_nodelist,t,node,ivalid,i);

		if (node)
		{
			//get the nodes tm
			Matrix3 objectTM = node->GetObjectTM(t);
			Matrix3 toLocalSpace = objectTM*baseTM;

			ObjectState tos =  node->EvalWorldState(t,TRUE);

			if (tos.obj->IsParticleSystem())
			{
				SimpleParticle* pobj      = NULL;
				IParticleObjectExt* epobj = NULL;
				pobj = static_cast<SimpleParticle*>( tos.obj->GetInterface(I_SIMPLEPARTICLEOBJ) );
				if (pobj)
				{
					pobj->UpdateParticles(t, node);

					int count = pobj->parts.Count();
					data.reserve(data.size() + count);
					float closest = 999999999.9f;
					SphereData d;
					for (int pid = 0; pid < count; pid++)
					{
						TimeValue age  = pobj->ParticleAge(t,pid);
						TimeValue life = pobj->ParticleLife(t,pid);
						if (age != -1)
						{
							float psize = pobj->ParticleSize(t,pid);
							Point3 curval = pobj->parts.points[pid];
							d.center = curval * baseTM;
							d.radius = psize;
							d.oradius = psize;
							d.rsquare = psize * psize;
							d.tover4 = tension * d.rsquare *d.rsquare ;
							data.push_back(d);
						}
					}
				}
				else
				{
					epobj = (IParticleObjectExt*) tos.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE);
					if (epobj) 
					{
						
						epobj->UpdateParticles(node, t);

						int count = epobj->NumParticles();
						data.reserve(data.size() + count);
						for (int pid = 0; pid < count; pid++)
						{
							TimeValue age  = epobj->GetParticleAgeByIndex(pid);
							if (age!=-1)
							{
								INode *node = epobj->GetParticleGroup(pid);

								Point3 *curval = epobj->GetParticlePositionByIndex(pid);

								BOOL useParticle = TRUE;

								if (!useAllPFEvents)
								{
									useParticle = FALSE;
									for (int k = 0; k < pfList.Count(); k++)
									{
										if (node == pfList[k])
										{
											useParticle = TRUE;
											k = pfList.Count();
										}
									}
								}

								if ((curval) && (useParticle))
								{
									float scale = epobj->GetParticleScaleByIndex(pid) ;
									float psize = scale;

									SphereData d;
									d.center = *curval*baseTM;
									d.radius = psize;
									d.oradius = psize;
									d.rsquare = psize * psize;
									d.tover4 = tension * d.rsquare *d.rsquare ;
									data.push_back(d);
								}
							}
						}
					}

				}
			}
			else if (tos.obj->IsShapeObject()) 
			{
				PolyShape shape;

				ShapeObject *pathOb = (ShapeObject*)tos.obj;
				pathOb->MakePolyShape(t, shape);
				
				// first find out how many points there are:
				size_t num_points = 0;
				for (int i = 0; i < shape.numLines; i++)
				{
					PolyLine& line = shape.lines[i];
					num_points += line.numPts;
				}
				data.reserve(data.size() + num_points);

				for (int i = 0; i < shape.numLines; i++)
				{
					PolyLine line = shape.lines[i];
					for (int j = 0; j < line.numPts; j++)
					{
						SphereData d;
						float tsize = size;
						d.center = line.pts[j].p*toLocalSpace;
						d.radius = tsize;
						d.oradius = tsize;
						d.rsquare = tsize * tsize;
						d.tover4 = tension * d.rsquare *d.rsquare ;
						data.push_back(d);
					}
				}
			}
			else if (tos.obj->SuperClassID()==GEOMOBJECT_CLASS_ID)
			{
				SphereData d;
				BOOL converted = FALSE;

				TriObject *triObj = NULL;


				if(tos.obj->IsSubClassOf(triObjectClassID)) 
				{
					triObj = (TriObject *)tos.obj;
				}

				// If it can convert to a TriObject, do it
				else if(tos.obj->CanConvertToType(triObjectClassID)) 
				{
					triObj = (TriObject *)tos.obj->ConvertToType(t, triObjectClassID);
					converted = TRUE;
				}

				if (triObj != NULL)
				{
					Mesh* mesh = &triObj->GetMesh();
					if (mesh)
					{
						int vcount = mesh->getNumVerts();
						float *vsw = mesh->getVSelectionWeights ();
						BitArray vsel =  mesh->VertSel();
						data.reserve(data.size() + vcount);
						for (int j = 0; j < vcount; j++)
						{
							float tsize = size;
							if (useSoftSel)
							{
								tsize = 0.0f;
								if (vsw)
								{
									float v = 0.0f;
									if (vsel[j]) 
										v = 1.0f;
									else 
									{
										if (vsw)
											v = vsw[j];
									}
									if (v == 0.0f)
										tsize = 0.0f;
									else
									{
										tsize = minSize + (size -minSize)*v;
									}

								}
								else
								{
									float v = 0.0f;
									if (vsel[j]) 
										v = 1.0f;
									tsize = minSize + (size -minSize)*v;
								}
							}
							if (tsize != 0.0f)
							{
								d.center = mesh->getVert(j)*toLocalSpace;
								d.radius = tsize;
								d.oradius = tsize;
								d.rsquare = tsize * tsize;
								d.tover4 = tension * d.rsquare *d.rsquare ;
								data.push_back(d);
							}
						}
					}

					if (converted) triObj->DeleteThis();
				}
			}
			else
			{
				SphereData d;
				d.center = Point3(0.0f,0.0f,0.0f)*toLocalSpace;
				d.radius = size;
				d.oradius = size;
				d.rsquare = size * size;
				d.tover4 = tension * d.rsquare *d.rsquare ;
				data.push_back(d);
			}
		}
	}


	if ((data.size() == 0) && (numberOfNodes==0))
	{
		data.resize(1);
		data[0].center = Point3(0.0f,0.0f,0.0f);
		data[0].radius = size;
		data[0].oradius = size;
		data[0].rsquare = size * size;
		data[0].tover4 = tension * data[0].rsquare *data[0].rsquare ;

	}

	if (data.size() > 0)
	{
		int iRes = 1;
		if (!largeDataSetOpt)
		{
			MetaParticle oldBlob;
			iRes = oldBlob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness);
		}
		else
		{
			MetaParticleFast blob;
			iRes = blob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness);
		}

		// An out of memory error is the only reason iRes would be zero in either case
		if( (iRes == 0) && GetCOREInterface() )
			GetCOREInterface()->DisplayTempPrompt(GetString(IDS_NOT_ENOUGH_MEM), 5000 );
	}
	else
	{
		mesh.setNumFaces(0);
		mesh.setNumVerts(0);
	}

	mesh.InvalidateTopologyCache();

	ivalid.Set(t,t);
}
//Some helper functions to handle painter UI
void PaintDeformTest::Paint()
{
	if (pPainter) //need to check this since some one could have taken the painterinterface plugin out
		{
		if (!pPainter->InPaintMode())  
			{
			pPainter->InitializeCallback(this); //initialize the callback
			//load up our nodes
			//gather up all our nodes and local data and store em off
			MyEnumProc dep;              
			DoEnumDependents(&dep);
			Tab<INode *> nodes;
			Tab<ObjectState> objList;
			painterNodeList.ZeroCount();
			TimeValue t = GetCOREInterface()->GetTime();
			for (int  i = 0; i < dep.Nodes.Count(); i++)
				{
				PaintDefromModData *pmd = GetPMD(dep.Nodes[i]);

				if (pmd)
					{
					nodes.Append(1,&dep.Nodes[i]);
					PainterNodeList temp;
					temp.node = dep.Nodes[i];
					temp.pmd = pmd;
					temp.tmToLocalSpace = Inverse(dep.Nodes[i]->GetObjectTM(GetCOREInterface()->GetTime()));
					painterNodeList.Append(1,&temp);
					ObjectState sos;
					sos = dep.Nodes[i]->EvalWorldState(t);
					objList.Append(1,&sos);
					}
				}

//we use the point gather so we need to tell the system to turn it on
			pPainter->SetEnablePointGather(TRUE);
			pPainter->SetBuildNormalData(TRUE);

//this sends all our dependant nodes to the painter
			pPainter->InitializeNodesByObjState(0, nodes,objList);

			BOOL updateMesh = FALSE;
			for (int i = 0; i < nodes.Count(); i++)
				{

				ObjectState os = nodes[i]->EvalWorldState(GetCOREInterface()->GetTime());
				
				int ct = os.obj->NumPoints();
//is our local vertex count does not match or the curremt object count we have some
//sort of topo change above us so we need to load a custom point list
//We really need add normals here
//so right now this does not work with patches, nurbs or things that have different  topos at the top
//top of the stack
				if (os.obj->NumPoints() != painterNodeList[i].pmd->offsetList.Count())
					{
					Tab<Point3> pointList;
					pointList.SetCount(ct);
					Matrix3 tm = nodes[i]->GetObjectTM(GetCOREInterface()->GetTime());
					for (int j =0; j < ct; j++)
						{
						pointList[j] = os.obj->GetPoint(j)*tm;
						}
					pPainter->LoadCustomPointGather(ct, pointList.Addr(0), nodes[i]);
					updateMesh = TRUE;
					}

				}
//reinitialize our nodes if we had a custom list
			if (updateMesh)
				pPainter->UpdateMeshesByObjState(TRUE,objList);

			pPainter->StartPaintSession(); //start the paint session
			iPaintButton->SetCheck(TRUE);
			}
		else //we are currently in a paint mode so turn it off
			{
			pPainter->EndPaintSession(); //end the paint session
			iPaintButton->SetCheck(FALSE);
			}
		}

}
void SelectByChannel::FillOutListBox()
{


	int mapID;
	int subID;

	pblock->GetValue(pb_mapid,0,mapID,FOREVER);
	pblock->GetValue(pb_mapsubid,0,subID,FOREVER);

	MyEnumProc dep;              
	DoEnumDependents(&dep);

	//reset the list box

	SendMessage(GetDlgItem(hWnd,IDC_SELCHANNELCOMBO),
				CB_RESETCONTENT ,0,0);

	channelList.ZeroCount();
	if (dep.Nodes.Count() > 0)
		{
		INode *node = dep.Nodes[0];
		for (int i = 0; i < 99; i++)
			{
			for (int j = 0; j < 3; j++)
				{
				TSTR key, name;
				key.printf(_T("MapChannel:%d(%d)"),i,j);
				if (node->UserPropExists(key))
					{
					node->GetUserPropString(key,name);
					if (name.Length() > 0)
						{
						TSTR lname;
						if (j==0)
							lname.printf(_T("%s %d-Red"),name,i);
						if (j==1)
							lname.printf(_T("%s %d-Green"),name,i);
						if (j==2)
							lname.printf(_T("%s %d-Blue"),name,i);


						SendMessage(GetDlgItem(hWnd,IDC_SELCHANNELCOMBO),
							CB_ADDSTRING,0,(LPARAM)(const TCHAR*)lname);					

						ChannelInfo data;
						data.mapID = i;
						data.subID = j;

						channelList.Append(1,&data);
						}
					}
				}
			}
		}

	int sel = -1;
	for (int i = 0; i < channelList.Count(); i++)
		{
		if ((mapID == channelList[i].mapID) && (subID == channelList[i].subID))
			sel = i;
		}

	SendMessage(GetDlgItem(hWnd,IDC_SELCHANNELCOMBO),CB_SETCURSEL  ,sel,0);


}