Exemple #1
0
void	UnwrapMod::BuildUsedList(BitArray &usedVerts, ClusterClass *cluster)
	{
	usedVerts.SetSize(TVMaps.v.Count());
	usedVerts.ClearAll();

	for (int j =0; j < cluster->faces.Count(); j++)
		{
		int faceIndex = cluster->faces[j];
		for (int k = 0; k <  TVMaps.f[faceIndex]->count; k++)
			{
//need to put patch handles in here also
			int index = TVMaps.f[faceIndex]->t[k];
			usedVerts.Set(index);
			if ((TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs))
				{
				index = TVMaps.f[faceIndex]->vecs->handles[k*2];
				if ((index >= 0) && (index < usedVerts.GetSize()))
					usedVerts.Set(index);

				index = TVMaps.f[faceIndex]->vecs->handles[k*2+1];
				if ((index >= 0) && (index < usedVerts.GetSize()))
					usedVerts.Set(index);

				if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR) 
					{
					index = TVMaps.f[faceIndex]->vecs->interiors[k];
					if ((index >= 0) && (index < usedVerts.GetSize()))
						usedVerts.Set(index);
					}
				}
			}
		}

	}
Exemple #2
0
void EChamferMod::ModifyTriObject (TimeValue t, ModContext &mc, TriObject *tobj) {
	Mesh &mesh = tobj->GetMesh();
	Interval iv = FOREVER;
	float amount;
	int i, j;
	
	m_pblock->GetValue (kEchAmount, t, amount, iv);

	// Convert existing selection (at whatever level) to edge selection:
	BitArray targetEdges;
	targetEdges.SetSize (mesh.numFaces*3);
	targetEdges.ClearAll ();

	switch (mesh.selLevel) {
	case MESH_OBJECT:
		targetEdges.SetAll ();
		break;
	case MESH_VERTEX:
		for (i=0; i<mesh.numFaces; i++) {
			for (j=0; j<3; j++) {
				if (!mesh.vertSel[mesh.faces[i].v[j]]) continue;
				// Don't select invisible edges:
				if (mesh.faces[i].getEdgeVis(j)) targetEdges.Set (i*3+j);
				if (mesh.faces[i].getEdgeVis((j+2)%3)) targetEdges.Set (i*3+(j+2)%3);
			}
		}
		break;
	case MESH_EDGE:
		targetEdges = mesh.edgeSel;
		break;
	case MESH_FACE:
		for (i=0; i<mesh.numFaces; i++) {
			if (!mesh.faceSel[i]) continue;
			for (j=0; j<3; j++) {
				// Don't select invisible edges:
				if (mesh.faces[i].getEdgeVis(j)) targetEdges.Set (i*3+j);
			}
		}
		break;
	}

	// Chamfer the edges -- this just does the topological operation.
	MeshDelta tmd;
	tmd.InitToMesh (mesh);
	MeshTempData temp;
	temp.SetMesh (&mesh);
	MeshChamferData *mcd = temp.ChamferData();
	AdjEdgeList *ae = temp.AdjEList();
	tmd.ChamferEdges (mesh, targetEdges, *mcd, ae);
	tmd.Apply (mesh);

	// Reset the meshdelta, temp data to deal with the post-chamfered topology:
	tmd.InitToMesh (mesh);
	temp.Invalidate (TOPO_CHANNEL);	// Generates a new edge list, but preserves chamfer data
	temp.SetMesh (&mesh);
	tmd.ChamferMove (mesh, *temp.ChamferData(), amount, temp.AdjEList());
	tmd.Apply (mesh);

	tobj->UpdateValidity(GEOM_CHAN_NUM,iv);		
}
void XTCSample::DeleteFaces(TimeValue t,Object *obj)
{
	if(bNF_OnOff)
	{
		Mesh *mesh = GetMesh(obj);
		
		if(!mesh)
			return;
		
		Interval ivalid = FOREVER;
		int nf;
		bo->GetParamBlockByID(x_params)->GetValue(pb_nf_spin,t,nf, ivalid);
		BitArray ba;
		ba.SetSize(mesh->getNumFaces());
		ba.ClearAll();
		
		for(int i = nf ; i < mesh->getNumFaces() ; i++ )
		{
			ba.Set(i);
		}
		
		if(!ba.IsEmpty())
			mesh->DeleteFaceSet(ba);
	}
}
Exemple #4
0
void VWeldMod::ConvertTriSelection (Mesh & mesh, BitArray & targetVerts) {
	targetVerts.SetSize (mesh.numVerts);
	targetVerts.ClearAll ();

	int i, j;
	switch (mesh.selLevel) {
	case MESH_OBJECT:
		targetVerts.SetAll ();
		break;
	case MESH_VERTEX:
		targetVerts = mesh.vertSel;
		break;
	case MESH_EDGE:
		for (i=0; i<mesh.numFaces; i++) {
			for (j=0; j<3; j++) {
				if (!mesh.edgeSel[i*3+j]) continue;
				targetVerts.Set (mesh.faces[i].v[j]);
				targetVerts.Set (mesh.faces[i].v[(j+1)%3]);
			}
		}
		break;
	case MESH_FACE:
		for (i=0; i<mesh.numFaces; i++) {
			if (!mesh.faceSel[i]) continue;
			for (j=0; j<3; j++) targetVerts.Set (mesh.faces[i].v[j]);
		}
		break;
	}
}
Exemple #5
0
void
UniformGrid::ClosestPoint(Point3 p, float radius, int &pindex, float &d)
{
	xHitList.ClearAll();
	yHitList.ClearAll();
	zHitList.ClearAll();
	hitList.SetCount(0);

	//find the cell in the XGrid
	TagCells(p,radius, 0);
	//find the cell in the YGrid
	TagCells(p,radius, 1);
	//find the cell in the ZGrid
	TagCells(p,radius, 2);

	BitArray usedList;
	usedList.SetSize(pointBase.Count());
	usedList.ClearAll();

	int closest = -1;
	d = 0.0f;
	Box3 localBounds;
	localBounds.Init();
	localBounds += p;
	localBounds.EnlargeBy(radius);


	for (int i = 0; i < hitList.Count(); i++)
	{
		int index = hitList[i];
		if (!usedList[index])  //check to see if we have processed this one or not
		{
			if (xHitList[index] && yHitList[index] && zHitList[index])
			{
				usedList.Set(index);
				Point3 source = pointBase[index];
				if (localBounds.Contains(source))
				{
					float dist = LengthSquared(source-p);
					if ((dist < d) || (closest == -1))
					{
						d = dist;
						closest = index;
					}
				}
			}
		}
	}
	pindex = closest;
	d = sqrt(d);


}
Exemple #6
0
void SymmetryMod::WeldTriObject (Mesh & mesh, Point3 & N, float offset, float threshold) {
	// Find vertices in target zone of mirror plane:
	BitArray targetVerts;
	targetVerts.SetSize (mesh.numVerts, true);
	targetVerts.ClearAll ();
	for (int i=0; i<mesh.numVerts; i++) {
		float dist = DotProd (N, mesh.verts[i]) - offset;
		if (fabsf(dist) > threshold) continue;
		targetVerts.Set (i);
	}

	// Weld the suitable border vertices:
	MeshDelta tmd(mesh);
	BOOL found = tmd.WeldByThreshold (mesh, targetVerts, threshold);
	tmd.Apply (mesh);
}
Exemple #7
0
void
UniformGrid::InRadius(Point3 p,  Tab<int> &indexList)
{
	float radius = largestRadius;
	xHitList.ClearAll();
	yHitList.ClearAll();
	zHitList.ClearAll();
	hitList.SetCount(0);

	//find the cell in the XGrid
	TagCells(p,radius, 0);
	//find the cell in the YGrid
	TagCells(p,radius, 1);
	//find the cell in the ZGrid
	TagCells(p,radius, 2);

	BitArray usedList;
	usedList.SetSize(pointBase.Count());
	usedList.ClearAll();

	int closest = -1;
	float d = 0.0f;
	Box3 localBounds;
	localBounds.Init();
	localBounds += p;
	localBounds.EnlargeBy(radius);


	for (int i = 0; i < hitList.Count(); i++)
	{
		int index = hitList[i];
		if (!usedList[index])  //check to see if we have processed this one or not
		{
			if (xHitList[index] && yHitList[index] && zHitList[index])
			{
				usedList.Set(index);
				Point3 source = pointBase[index];
				if (localBounds.Contains(source))
				{
					indexList.Append(1,&index,1000);

				}
			}
		}
	}

}
Exemple #8
0
void UVW_ChannelClass::MarkDeadVertices()
	{
	BitArray usedVerts;
	usedVerts.SetSize(v.Count());
	usedVerts.ClearAll();

	for (int i =0; i < f.Count(); i++)
		{
		if (!(f[i]->flags & FLAG_DEAD))
			{
			for (int j=0; j < f[i]->count; j++)
				{
				int id = f[i]->t[j];
				if (id < usedVerts.GetSize()) usedVerts.Set(id);
				if ((f[i]->flags & FLAG_CURVEDMAPPING) && (f[i]->vecs))
					{
					id = f[i]->vecs->handles[j*2];
					if (id < usedVerts.GetSize()) usedVerts.Set(id);
					id = f[i]->vecs->handles[j*2+1];
					if (id < usedVerts.GetSize()) usedVerts.Set(id);
					if (f[i]->flags & FLAG_INTERIOR)
						{
						id = f[i]->vecs->interiors[j];
						if (id < usedVerts.GetSize()) usedVerts.Set(id);
						}
					}
	
				}
			}
		}

	for (int i =0; i < v.Count(); i++)
		{
		if (i < usedVerts.GetSize())
			{
			BOOL isRigPoint = v[i].GetFlag() & FLAG_RIGPOINT;
			if (!usedVerts[i] && (!isRigPoint))
				{
				v[i].SetDead();
				}
			}
		
		}
	

	}
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
//|							From IPFTest									 |
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
bool PFTestSplitBySource::Proceed(IObject* pCont, 
							PreciseTimeValue timeStart, 
							PreciseTimeValue& timeEnd, 
							Object* pSystem, 
							INode* pNode, 
							INode* actionNode, 
							IPFIntegrator* integrator, 
							BitArray& testResult, 
							Tab<float>& testTime)
{
	if (pNode == NULL) return false;

	bool exactStep = IsExactIntegrationStep(timeEnd, pSystem);
	int conditionType	= pblock()->GetInt(kSplitBySource_conditionType, timeStart);

	// acquire absolutely necessary particle channels
	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if (chAmount == NULL) return false; // can't find number of particles in the container
	int count = chAmount->Count();

	bool isSelectedSource = false;
	int i, systemHandle = pNode->GetHandle();
	for(i=0; i<pblock()->Count(kSplitBySource_sources); i++) {
		if (systemHandle == pblock()->GetInt(kSplitBySource_sources, 0, i)) {
			isSelectedSource = true; break;
		}
	}
				
	// test all particles
	testResult.SetSize(count);
	testResult.ClearAll();
	testTime.SetCount(count);
	if (exactStep) {
		if ((isSelectedSource && (conditionType == kSplitBySource_conditionType_selected)) 
			|| (!isSelectedSource && (conditionType == kSplitBySource_conditionType_notSelected))) {
			testResult.SetAll();
			for(i=0; i<count; i++) testTime[i] = 0.0f;
		}
	}

	return true;
}
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
//|							From IPFTest									 |
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
bool PFTestGoToNextEvent::Proceed(IObject* pCont, 
							PreciseTimeValue timeStart, 
							PreciseTimeValue& timeEnd, 
							Object* pSystem, 
							INode* pNode, 
							INode* actionNode, 
							IPFIntegrator* integrator, 
							BitArray& testResult, 
							Tab<float>& testTime)
{
	int conditionType	= pblock()->GetInt(kGoToNextEvent_conditionType, timeStart);
	bool exactStep = IsExactIntegrationStep(timeEnd, pSystem);

	// get channel container interface
	IChannelContainer* chCont;
	chCont = GetChannelContainerInterface(pCont);
	if (chCont == NULL) return false;

	// acquire absolutely necessary particle channels
	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if (chAmount == NULL) return false; // can't find number of particles in the container
	IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
	if (chTime == NULL) return false; // can't read timing info for a particle

	int count = chAmount->Count();
	if (count <= 0) return true;

	testResult.SetSize(count);
	testTime.SetCount(count);
	if((conditionType == kGoToNextEvent_conditionType_all) && exactStep) {
		testResult.SetAll();
		for(int i=0; i<count; i++) testTime[i] = 0.0f;
	} else {
		testResult.ClearAll();
	}

	return true;
}
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
//|							From IPFTest									 |
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
bool PFTestSplitSelected::Proceed(IObject* pCont, 
							PreciseTimeValue timeStart, 
							PreciseTimeValue& timeEnd, 
							Object* pSystem, 
							INode* pNode, 
							INode* actionNode, 
							IPFIntegrator* integrator, 
							BitArray& testResult, 
							Tab<float>& testTime)
{
	bool exactStep = IsExactIntegrationStep(timeEnd, pSystem);
	int conditionType	= pblock()->GetInt(kSplitSelected_conditionType, timeStart);

	// acquire absolutely necessary particle channels
	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if (chAmount == NULL) return false; // can't find number of particles in the container
	int count = chAmount->Count();
	IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
	if (chTime == NULL) return false; // can't read timing info for a particle
	IParticleChannelBoolR* chSelect = GetParticleChannelSelectionRInterface(pCont);

	// test all particles
	testResult.SetSize(count);
	testResult.ClearAll();
	testTime.SetCount(count);
	for(int i=0; i<count; i++)
	{
		bool selected = (chSelect != NULL) ? chSelect->GetValue(i) : false;
		bool sendOut = ((selected && (conditionType == kSplitSelected_conditionType_selected)) 
						|| (!selected && (conditionType == kSplitSelected_conditionType_notSelected)));
		if (sendOut && exactStep) {
			testResult.Set(i);
			testTime[i] = 0.0f;
		}
	}
	return true;
}
Exemple #12
0
void SymmetryMod::SliceTriObject (Mesh & mesh, Point3 & N, float offset) {
	// Steve Anderson 9/14/2002
	// Using the new "MESH_TEMP_1" flag to override Slice selection behavior,
	// which is undesirable here.
	mesh.SetFlag (MESH_TEMP_1);
	MeshDelta slicemd;
	slicemd.Slice (mesh, N, offset, false, true);
	slicemd.Apply (mesh);
	mesh.ClearFlag (MESH_TEMP_1);

	// We need to strip out faces on the mirror plane itself.
	// (These aren't always removed by slice.)

	// Mark vertices at the plane boundary:
	BitArray targetVerts;
	targetVerts.SetSize (mesh.numVerts);
	targetVerts.ClearAll ();
	for (int i=0; i<mesh.numVerts; i++) {
		float dist = DotProd (N, mesh.verts[i]) - offset;
		if (fabsf(dist) > MNEPS) continue;
		targetVerts.Set (i);
	}
	BitArray delFaces, delVerts;
	delFaces.SetSize (mesh.numFaces);
	for (int i=0; i<mesh.numFaces; i++) {
      int j;
		for (j=0; j<3; j++) {
			if (!targetVerts[mesh.faces[i].v[j]]) break;
		}
		if (j<3) continue;
		// Face needs to be deleted.
		delFaces.Set (i);
	}
	mesh.DeleteFaceSet (delFaces, &delVerts);
	mesh.DeleteVertSet (delVerts);
}
void	MeshTopoData::UpdateClusterVertices(Tab<ClusterClass*> &clusterList)
{
	BitArray processedVerts;
	processedVerts.SetSize(TVMaps.v.Count());

	for (int i = 0; i < clusterList.Count(); i++)
	{
		
		if (clusterList[i]->ld == this)
		{
			clusterList[i]->verts.SetCount(0);
			processedVerts.ClearAll();
			for (int j = 0; j < clusterList[i]->faces.Count(); j++)
			{
				int findex = clusterList[i]->faces[j];
				AddVertsToCluster(findex, processedVerts, clusterList[i]);
			}
			for (int j = 0; j < clusterList[i]->verts.Count(); j++)
			{
				int id = clusterList[i]->verts[j];
			}
		}
	}
}
Exemple #14
0
//pelt
void UVW_ChannelClass::EdgeListFromPoints(Tab<int> &selEdges, int source, int target, Point3 vec)
{
	//make sure point a and b are on the same element if not bail
	Tab<VConnections*> ourConnects;
	BOOL del = FALSE;

	BitArray selVerts;
	selVerts.SetSize(geomPoints.Count());
	selVerts.ClearAll();

//	if (TRUE)
	
		//loop through the edges
		Tab<int> numberOfConnections;
		numberOfConnections.SetCount(geomPoints.Count());
		for (int i = 0; i < geomPoints.Count(); i++)
		{
			numberOfConnections[i] = 0;
		}
		//count the number of vertxs connected
		for (int i = 0; i < gePtrList.Count(); i++)
		{
			if (!(gePtrList[i]->flags & FLAG_HIDDENEDGEA))
			{
				int a = gePtrList[i]->a;
				numberOfConnections[a] +=1;
				int b = gePtrList[i]->b;
				numberOfConnections[b] +=1;
			}
		}
		//allocate our connections now

		ourConnects.SetCount(geomPoints.Count());
		for (int i = 0; i < geomPoints.Count(); i++)
		{
			ourConnects[i] = new VConnections();
			ourConnects[i]->closestNode = NULL;
			ourConnects[i]->linkedListChild = NULL;
			ourConnects[i]->linkedListParent = NULL;
			ourConnects[i]->accumDist = 1.0e+9f;
			ourConnects[i]->solved = FALSE;
			ourConnects[i]->vid = i;

			ourConnects[i]->connectingVerts.SetCount(numberOfConnections[i]);
		}

		for (int i = 0; i < geomPoints.Count(); i++)
		{
			numberOfConnections[i] = 0;
		}

		//build our vconnection data
		for (int i = 0; i < gePtrList.Count(); i++)
		{
			if (!(gePtrList[i]->flags & FLAG_HIDDENEDGEA))
			{
				int a = gePtrList[i]->a;
				int b = gePtrList[i]->b;

				int index = numberOfConnections[a];
				ourConnects[a]->connectingVerts[index].vertexIndex = b;
				ourConnects[a]->connectingVerts[index].edgeIndex = i;
				numberOfConnections[a] +=1;

				index = numberOfConnections[b];
				ourConnects[b]->connectingVerts[index].vertexIndex = a;
				ourConnects[b]->connectingVerts[index].edgeIndex = i;
				numberOfConnections[b] +=1;
			}
		}


		del = TRUE;
	
	//	else ourConnects = vConnects;

	//spider out till hit our target or no more left
	BOOL done = FALSE;
	BOOL hit = FALSE;
	Tab<int> vertsToDo;
	BitArray processedVerts;
	processedVerts.SetSize(ourConnects.Count());
	processedVerts.ClearAll();

	//if no more left bail
	int currentVert = source;
	while (!done)
	{
		//	int startingNumberProcessed = processedVerts.NumberSet();

		int ct = ourConnects[currentVert]->connectingVerts.Count();
		processedVerts.Set(currentVert, TRUE);
		for (int j = 0; j < ct; j++)
		{
			int index = ourConnects[currentVert]->connectingVerts[j].vertexIndex;
			if (index == target) 
			{
				done = TRUE;
				hit = TRUE;
			}
			if (!processedVerts[index])
				vertsToDo.Append(1,&index, 10000);
		}

		if (vertsToDo.Count())
		{
			currentVert = vertsToDo[vertsToDo.Count()-1];
			vertsToDo.Delete(vertsToDo.Count()-1,1);
		}

		if (vertsToDo.Count() == 0) done = TRUE;
		//		int endingNumberProcessed = processedVerts.NumberSet();

		if (currentVert == target) 
		{
			done = TRUE;
			hit = TRUE;
		}
		//		if (startingNumberProcessed == endingNumberProcessed)
		//			done = TRUE;
	}
	vertsToDo.ZeroCount();

 	if (hit)
	{
		Tab<VConnections*> solvedNodes;

		ourConnects[source]->accumDist = 0;

		VConnections* unsolvedNodeHead = ourConnects[source];
		VConnections* unsolvedNodeCurrent = unsolvedNodeHead;
		
		//put all our vertices in the unsolved list
		
		for (int i = 0; i < ourConnects.Count(); i++)
		{			
			if (ourConnects[i] != unsolvedNodeHead)
			{
				unsolvedNodeCurrent->linkedListChild = ourConnects[i];
				VConnections *parent = unsolvedNodeCurrent;
				unsolvedNodeCurrent = ourConnects[i];
				unsolvedNodeCurrent->linkedListParent = parent;
			}
		}

		//build our edge distances
		Tab<float> edgeDistances;
		edgeDistances.SetCount(gePtrList.Count());
		for (int i = 0 ; i < gePtrList.Count(); i++)
		{
			int a = gePtrList[i]->a;
			int b = gePtrList[i]->b;
			float d = Length(geomPoints[a] - geomPoints[b]);
			edgeDistances[i] = d;

		}


		BOOL done = FALSE;
		while (!done)
		{
			//pop the top unsolved
			VConnections *top = unsolvedNodeHead;


			unsolvedNodeHead = unsolvedNodeHead->linkedListChild;
			top->linkedListChild = NULL;
			top->linkedListParent = NULL;
			if (unsolvedNodeHead != NULL)
			{
				unsolvedNodeHead->linkedListParent = NULL;
				//mark it as processed
				top->solved = TRUE;
				
				//put it in our solved list
				solvedNodes.Append(1,&top,5000);

				int neighborCount = top->connectingVerts.Count();
				//loop through the neighbors
				for (int i = 0; i < neighborCount; i++)
				{
					int index  = top->connectingVerts[i].vertexIndex;
					int eindex  = top->connectingVerts[i].edgeIndex;
					VConnections *neighbor = ourConnects[index];
					//make sure it is not procssedd
					if (!neighbor->solved)
					{
						//find the distance from the top to this neighbor
						float d = neighbor->accumDist;
						float testAccumDistance = top->accumDist + edgeDistances[eindex];
						//see if it accum dist needs to be relaxed
						if (testAccumDistance<d)
						{
							float originalDist = neighbor->accumDist;
							neighbor->accumDist = testAccumDistance;
							neighbor->closestNode = top;
							//sort this node
							float dist = neighbor->accumDist;


							if (originalDist == 1.0e+9f)
							{
								//start at the top and look down
								VConnections *currentNode = unsolvedNodeHead;
								if (neighbor == currentNode)
								{
									currentNode = currentNode->linkedListChild;
									unsolvedNodeHead = currentNode;
								}
								VConnections *prevNode = NULL;
								//unhook node
								VConnections *parent = neighbor->linkedListParent;
								VConnections *child = neighbor->linkedListChild;
								if (parent)
									parent->linkedListChild = child;
								if (child)
									child->linkedListParent = parent;
									

								while ((currentNode!= NULL) && (currentNode->accumDist < dist))
								{
								
									prevNode = currentNode;
									currentNode = currentNode->linkedListChild;
									SHORT iret = GetAsyncKeyState (VK_ESCAPE);
									if (iret==-32767)
									{
										done = TRUE;
										currentNode= NULL;
									}
								}
								//empty list
								if ((prevNode==NULL) && (currentNode== NULL))
								{
									neighbor->linkedListChild = NULL;
									neighbor->linkedListParent = NULL;
									unsolvedNodeHead = neighbor;
								}
								//at top
								else if (currentNode && (prevNode == NULL))
								{
									unsolvedNodeHead->linkedListParent = neighbor;
									neighbor->linkedListParent = NULL;
									neighbor->linkedListChild =unsolvedNodeHead;
									unsolvedNodeHead = neighbor;

								}
								//at bottom
								else if (currentNode == NULL)
								{
									prevNode->linkedListChild = neighbor;
									neighbor->linkedListParent = currentNode;
									neighbor->linkedListChild = NULL;
								}

								else if (currentNode)
								{
									//insert
									VConnections *parent = currentNode->linkedListParent;
									VConnections *child = currentNode;
		
									parent->linkedListChild = neighbor;
									child->linkedListParent = neighbor;

									neighbor->linkedListParent = parent;
									neighbor->linkedListChild = child;

								}



							}
							else
							{
								//sort smallest to largest
								BOOL moveUp = FALSE;

								if (neighbor->linkedListParent && neighbor->linkedListChild)
								{
									float parentDist = neighbor->linkedListParent->accumDist;
									float childDist = neighbor->linkedListChild->accumDist;
									//walkup up or down the list till find a spot an unlink and relink
									
									if ((dist >= parentDist) && (dist <= childDist))
									{
										//done dont need to move
									}
									else if (dist < parentDist)
										moveUp = FALSE;
								}
								else if (neighbor->linkedListParent && (neighbor->linkedListChild==NULL))
								{
									moveUp = TRUE;
								}
								else if ((neighbor->linkedListParent==NULL) && (neighbor->linkedListChild))
								{
									moveUp = FALSE;
								}

								//unlink the node
								//unhook node
								VConnections *parent = neighbor->linkedListParent;
								VConnections *child = neighbor->linkedListChild;
								if (parent)
									parent->linkedListChild = child;
								else unsolvedNodeHead = child;
								if (child)
									child->linkedListParent = parent;

								VConnections *currentNode = NULL;
								if (moveUp)
									currentNode = neighbor->linkedListParent;
								else currentNode = neighbor->linkedListChild;
								VConnections *prevNode = NULL;

								while ((currentNode!= NULL) && (currentNode->accumDist < dist))
								{							
									prevNode = currentNode;
									if (moveUp)
										currentNode = currentNode->linkedListParent;
									else currentNode = currentNode->linkedListChild;

									SHORT iret = GetAsyncKeyState (VK_ESCAPE);
									if (iret==-32767)
									{
										done = TRUE;
										currentNode= NULL;
									}

								}

								//empty list
								if ((prevNode==NULL) && (currentNode== NULL))
								{
									neighbor->linkedListChild = NULL;
									neighbor->linkedListParent = NULL;
									unsolvedNodeHead = neighbor;
								}
								//at top
								else if (currentNode && (prevNode == NULL))
								{
									unsolvedNodeHead->linkedListParent = neighbor;
									neighbor->linkedListParent = NULL;
									neighbor->linkedListChild =unsolvedNodeHead;
									unsolvedNodeHead = neighbor;

								}
								//at bottom
								else if (currentNode == NULL)
								{
									prevNode->linkedListChild = neighbor;
									neighbor->linkedListParent = currentNode;
									neighbor->linkedListChild = NULL;
								}
								else if (currentNode)
								{
									//insert
									VConnections *parent = currentNode->linkedListParent;
									VConnections *child = currentNode;
		
									parent->linkedListChild = neighbor;
									child->linkedListParent = neighbor;

									neighbor->linkedListParent = parent;
									neighbor->linkedListChild = child;

								}


							}

						}					
					}
				}
			}
			

			if (unsolvedNodeHead == NULL)
				done = TRUE;
			if ((solvedNodes[solvedNodes.Count()-1]) == ourConnects[target])
				done = TRUE;
		}
		//now get our edge list
		selEdges.ZeroCount();
		VConnections *cNode = ourConnects[target];
		while ((cNode->closestNode != NULL) && (cNode != ourConnects[source]))
		{
			VConnections *pNode = cNode->closestNode;
			int ct = cNode->connectingVerts.Count();
			int edgeIndex = -1;
			for (int i = 0; i < ct; i++)
			{
				int vindex = cNode->connectingVerts[i].vertexIndex;
				int eindex = cNode->connectingVerts[i].edgeIndex;
				if (ourConnects[vindex] == pNode)
				{
					edgeIndex = eindex;
					i = ct;
				}
			}
			if (edgeIndex != -1)
				selEdges.Append(1,&edgeIndex,500);

			cNode = pNode;
		}

	}

	if (del)
	{
		for (int i = 0; i < geomPoints.Count(); i++)
		{
			delete ourConnects[i];
		}
	}
}
void MeshTopoData::BuildInitialMapping(MNMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();

	int vertCount = 0;
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		vertCount += pcount;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
		}

	}

	vertCount = msh->numv;
	Tab<int> indexList;

	indexList.SetCount(vertCount);
	BitArray usedIndex;
	usedIndex.SetSize(vertCount);
	usedIndex.ClearAll();

	for (int i = 0; i < vertCount; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			for (int j = 0; j < pcount; j++)
			{
				usedIndex.Set(msh->f[i].vtx[j]);
			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->f[i].vtx[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f );
				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);

			}

		}
	}

}
Exemple #16
0
void UVW_ChannelClass::SplitUVEdges(BitArray esel)
{
	
	//get our point selection from the edges
	BitArray pointSel;
	pointSel.SetSize(v.Count());
	pointSel.ClearAll();
	for (int i = 0; i < ePtrList.Count(); i++)
	{
		if (esel[i])
		{
			int a = ePtrList[i]->a;
			int b = ePtrList[i]->b;
			pointSel.Set(a,TRUE);
			pointSel.Set(b,TRUE);
		}
	}

//build a lis of egdes for each vert
	Tab<VEdges*> edgesAtVertex;
	edgesAtVertex.SetCount(v.Count());
	for (int i = 0; i < v.Count(); i++)
		edgesAtVertex[i] = NULL;

	for (int i = 0; i < ePtrList.Count(); i++)
	{
		int a = ePtrList[i]->a;
		if (pointSel[a])
		{
			if (edgesAtVertex[a] == NULL)
				edgesAtVertex[a] = new VEdges();

			edgesAtVertex[a]->edgeIndex.Append(1,&i,5);
		}

		a = ePtrList[i]->b;
		if (pointSel[a])
		{
			if (edgesAtVertex[a] == NULL)
				edgesAtVertex[a] = new VEdges();

			edgesAtVertex[a]->edgeIndex.Append(1,&i,5);
		}

	}

	BitArray processedFaces;
	processedFaces.SetSize(f.Count());

	BitArray processedEdges;
	processedEdges.SetSize(ePtrList.Count());

	int originalCount = v.Count();
	for (int i = 0; i < originalCount; i++)
	{
		if (pointSel[i])
		{
			processedFaces.ClearAll();
			processedEdges.ClearAll();

			int ct = edgesAtVertex[i]->edgeIndex.Count();
			BOOL first = TRUE;


			for (int j = 0; j < ct; j++)
			{
				int currrentEdgeIndex =  edgesAtVertex[i]->edgeIndex[j];
				//find a selected edge
				if (esel[currrentEdgeIndex])
				{

					int numFaces = ePtrList[currrentEdgeIndex]->faceList.Count();

					for (int m = 0; m < numFaces; m++)
					{
						int newVertIndex = -1;
						if (first)
						{
							//just set the index
							newVertIndex = i;
							first = FALSE;
						}
						else
						{
							//create a new vertex 
							UVW_TVVertClass newVert;
							newVert.SetP(v[i].GetP());
							newVert.SetInfluence(0.0f);
							newVert.SetFlag(0);
							//create a new handle if we need one
							v.Append(1,&newVert);

							newVertIndex = v.Count()-1;
						}
						int currentFaceIndex = ePtrList[currrentEdgeIndex]->faceList[m];
						if (!processedFaces[currentFaceIndex])
						{
							BOOL done = FALSE;
							int lastEdge = j;
							while (!done)
							{
								//loop through this face looking for matching vert
								int deg = f[currentFaceIndex]->count;
								for (int n = 0; n < deg; n++)
								{
									//replace it
									if (f[currentFaceIndex]->t[n] == i)
									{
										f[currentFaceIndex]->t[n] = newVertIndex;
									}
								}
								processedFaces.Set(currentFaceIndex,TRUE);

								//loop til we find another selected face or an opent edge
								int nextEdge = -1;								
								for (int n = 0; n < ct; n++)
								{
									//mkae sure we are not looking at the current edge
									int potentialEdge = edgesAtVertex[i]->edgeIndex[n];
									if (n != lastEdge)
									{										
										int nfaces = ePtrList[potentialEdge]->faceList.Count();
										if (nfaces != -1)
										{
											for (int p = 0; p < nfaces; p++)
											{
												if (ePtrList[potentialEdge]->faceList[p] == currentFaceIndex)
												{
													nextEdge = potentialEdge;
													lastEdge = n;
													p = nfaces;
													n = ct; 
												}
											}
										}
									}
								}
								//if we hit an edge we are done with this cluster
								if (nextEdge==-1)
									done = TRUE;
								else if (ePtrList[nextEdge]->a == ePtrList[nextEdge]->b)
									done = TRUE;
								else if (esel[nextEdge])
									done = TRUE;
								else if (nextEdge != -1)
								{
									//get the next face
									int nfaces = ePtrList[nextEdge]->faceList.Count();
									BOOL hit = FALSE;
									for (int p = 0; p < nfaces; p++)
									{
										if (ePtrList[nextEdge]->faceList[p]!= currentFaceIndex)
										{
											currentFaceIndex = ePtrList[nextEdge]->faceList[p];
											hit = TRUE;
											p = nfaces;
										}
									}
									if (!hit) done = TRUE;

								}



							}
						}
					}
				}
			}
		}
	}

	for (int i = 0; i < originalCount; i++)
	{
		if (edgesAtVertex[i])
			delete edgesAtVertex[i];
		
	}


	

	BuildEdges();
	BuildGeomEdges();

	Tab<int> numberConnectedEdges;
	numberConnectedEdges.SetCount(v.Count());
	for (int i = 0; i < v.Count(); i++)
	{
		numberConnectedEdges[i] = 0;
	}
//loop through our egdes
	for (int i = 0; i < ePtrList.Count(); i++)
	{
		int veca = ePtrList[i]->avec;
		int vecb = ePtrList[i]->bvec;
		if (veca != -1)
			numberConnectedEdges[veca] += 1;
		if (vecb != -1)
			numberConnectedEdges[vecb] += 1;
	}

	for (int i = 0; i < f.Count(); i++)
	{
		if (f[i]->vecs)
		{
			int deg = f[i]->count;
			for (int j = 0; j < deg*2; j++)
			{
				int va;
				va = f[i]->vecs->handles[j];
				if (numberConnectedEdges[va] > 1)
				{
					//clone the vert
					UVW_TVVertClass newVert;
					newVert.SetP(v[va].GetP());
					newVert.SetInfluence(0.0f);
					newVert.SetFlag(0);
					//create a new handle if we need one
					v.Append(1,&newVert);

					int newVertIndex = v.Count()-1;
					//assign it
					f[i]->vecs->handles[j] = newVertIndex;
					//dec our counrt
					numberConnectedEdges[va] -= 1;
				}
			}
		}
	}

	mSystemLockedFlag.SetSize(v.Count(), 1);

	BuildEdges();
	BuildGeomEdges();

	

}
Exemple #17
0
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
//|							From IPFTest									 |
//+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+
bool PFTestSpeed::Proceed(IObject* pCont, 
							PreciseTimeValue timeStart, 
							PreciseTimeValue& timeEnd, 
							Object* pSystem, 
							INode* pNode, 
							INode* actionNode, 
							IPFIntegrator* integrator, 
							BitArray& testResult, 
							Tab<float>& testTime)
{
	bool exactStep = IsExactIntegrationStep(timeEnd, pSystem);

	// get the constant properties of the test
	int testType = pblock()->GetInt(kSpeedTest_testType, timeEnd);
	int condType = pblock()->GetInt(kSpeedTest_conditionType, timeEnd);
	int syncType = pblock()->GetInt(kSpeedTest_sync, timeEnd);
	ParamID varParamID = (testType == kSpeedTest_testType_steering) ? kSpeedTest_angleVariation : kSpeedTest_unitVariation;
	bool hasTestVariation = (pblock()->GetFloat(varParamID, 0) != 0.0f);
	if (!hasTestVariation) {
		Control* ctrl = pblock()->GetControllerByID(varParamID);
		if (ctrl != NULL)
			hasTestVariation = (ctrl->IsAnimated() != 0);
	}
	if (testType >= kSpeedTest_testType_whenAccels) {
		hasTestVariation = false;
		syncType = kSpeedTest_sync_time;
	}
	bool needPrevValue = (testType >= kSpeedTest_testType_accel);

	// get channel container interface
	IChannelContainer* chCont;
	chCont = GetChannelContainerInterface(pCont);
	if (chCont == NULL) return false;

	// acquire absolutely necessary particle channels
	IParticleChannelAmountR* chAmount = GetParticleChannelAmountRInterface(pCont);
	if (chAmount == NULL) return false; // can't find number of particles in the container
	int count = chAmount->Count();
	if (count == 0) return true; // no particles to test
	IParticleChannelPTVR* chTime = GetParticleChannelTimeRInterface(pCont);
	if (chTime == NULL) return false; // can't read timing info for a particle
	IParticleChannelNewR* chNew = GetParticleChannelNewRInterface(pCont);
	if (chNew == NULL) return false; // can't find newly entered particles for duration calculation
	IParticleChannelPoint3R* chSpeed = GetParticleChannelSpeedRInterface(pCont);
	if (chSpeed == NULL) return false; // can't read speed values

	// acquire more particle channels
	IParticleChannelPTVR* chBirthTime = NULL;
	if (syncType == kSpeedTest_sync_age && (testType < kSpeedTest_testType_whenAccels))
	{
		chBirthTime = GetParticleChannelBirthTimeRInterface(pCont);
		if (chBirthTime == NULL) return false; // can't read particle age
	}
	IParticleChannelPTVR* chEventStartR = NULL;
	IParticleChannelPTVW* chEventStartW = NULL;
	bool initEventStart = false;
	if (syncType == kSpeedTest_sync_event && (testType < kSpeedTest_testType_whenAccels)) {
		chEventStartR = (IParticleChannelPTVR*)chCont->EnsureInterface(PARTICLECHANNELEVENTSTARTR_INTERFACE,
																		ParticleChannelPTV_Class_ID,
																		true, PARTICLECHANNELEVENTSTARTR_INTERFACE,
																		PARTICLECHANNELEVENTSTARTW_INTERFACE, false,
																		actionNode, NULL, &initEventStart);
		if (chEventStartR == NULL) return false; // can't read event start time
		if (initEventStart) {
			chEventStartW = GetParticleChannelEventStartWInterface(pCont);
			if (chEventStartW == NULL) return false; // can't write event start time
		}
	}
	IParticleChannelFloatR* chRandFloatR = NULL;
	IParticleChannelFloatW* chRandFloatW = NULL;
	bool initRandFloat = false;
	if (hasTestVariation) {
		chRandFloatW = (IParticleChannelFloatW*)chCont->EnsureInterface(PARTICLECHANNELRANDFLOATW_INTERFACE,
																		ParticleChannelFloat_Class_ID,
																		true, PARTICLECHANNELRANDFLOATR_INTERFACE,
																		PARTICLECHANNELRANDFLOATW_INTERFACE, true,
																		actionNode, (Object*)this, &initRandFloat);
		chRandFloatR = (IParticleChannelFloatR*)chCont->GetPrivateInterface(PARTICLECHANNELRANDFLOATR_INTERFACE, (Object*)this);
		if ((chRandFloatR == NULL) || (chRandFloatW == NULL)) return false; // can't set rand float value for newly entered particles
	}
	IParticleChannelPoint3R* chPrevSpeedR = NULL;
	IParticleChannelPoint3W* chPrevSpeedW = NULL;
	IParticleChannelPTVR* chPrevTimeR = NULL;
	IParticleChannelPTVW* chPrevTimeW = NULL;
	bool initPrevValue = false;
	if (needPrevValue) {
		chPrevSpeedW = (IParticleChannelPoint3W*)chCont->EnsureInterface(PARTICLECHANNELPREVSPEEDW_INTERFACE,
																		ParticleChannelPoint3_Class_ID,
																		true, PARTICLECHANNELPREVSPEEDR_INTERFACE,
																		PARTICLECHANNELPREVSPEEDW_INTERFACE, true,
																		actionNode, (Object*)this, &initPrevValue);
		chPrevSpeedR = (IParticleChannelPoint3R*)chCont->GetPrivateInterface(PARTICLECHANNELPREVSPEEDR_INTERFACE, (Object*)this);
		chPrevTimeW = (IParticleChannelPTVW*)chCont->EnsureInterface(PARTICLECHANNELPREVTIMEW_INTERFACE,
																		ParticleChannelPTV_Class_ID,
																		true, PARTICLECHANNELPREVTIMER_INTERFACE,
																		PARTICLECHANNELPREVTIMEW_INTERFACE, true,
																		actionNode, (Object*)this, &initPrevValue);
		chPrevTimeR = (IParticleChannelPTVR*)chCont->GetPrivateInterface(PARTICLECHANNELPREVTIMER_INTERFACE, (Object*)this);
		if ((chPrevSpeedR == NULL) || (chPrevSpeedW == NULL) || (chPrevTimeR == NULL) || (chPrevTimeW == NULL)) return false; 
	}

	// grab the rand generator for test variation
	RandGenerator* randGen = randLinker().GetRandGenerator(pCont);
	if (randGen == NULL) return false;

	// check all particles
	testResult.SetSize(count);
	testResult.ClearAll();
	testTime.SetCount(count);
	for(int i=0; i<count; i++)
	{
		if (chNew->IsNew(i)) { // initialize some channels
			if (initEventStart)
				chEventStartW->SetValue(i, chTime->GetValue(i));
			if (initRandFloat)
				chRandFloatW->SetValue(i, randGen->Rand11());
		}

		PreciseTimeValue prevTime;
		Point3 prevSpeed;
		Point3 currentSpeed = chSpeed->GetValue(i);
		PreciseTimeValue currentTime = chTime->GetValue(i);
		if (needPrevValue) {
			prevTime = chPrevTimeR->GetValue(i);
			prevSpeed = chPrevSpeedR->GetValue(i);
			chPrevTimeW->SetValue(i, currentTime);
			chPrevSpeedW->SetValue(i, currentSpeed);
			if (initPrevValue && chNew->IsNew(i))
				continue; // particle just came into the event and doesn't have previous value
		}

		PreciseTimeValue syncTime = currentTime;
		switch(syncType) {
		case kSpeedTest_sync_age:
			syncTime -= chBirthTime->GetValue(i);
			break;
		case kSpeedTest_sync_event:
			syncTime -= chEventStartR->GetValue(i);
			break;
		}
		TimeValue syncTimeTV = TimeValue(syncTime);

		float testValue = 0.0f;
		if (testType < kSpeedTest_testType_whenAccels) {
			if (testType == kSpeedTest_testType_steering) {
				testValue = GetPFFloat(pblock(), kSpeedTest_angleValue, syncTimeTV);
				if (hasTestVariation)
					testValue += chRandFloatR->GetValue(i)*GetPFFloat(pblock(), kSpeedTest_angleVariation, syncTimeTV);
			} else {
				testValue = GetPFFloat(pblock(), kSpeedTest_unitValue, syncTimeTV);
				if (hasTestVariation)
					testValue += chRandFloatR->GetValue(i)*GetPFFloat(pblock(), kSpeedTest_unitVariation, syncTimeTV);
			}
			testValue /= TIME_TICKSPERSEC;
		}

		float currentValue = 0.0f;
		bool testSatisfied = false;
		if (testType < kSpeedTest_testType_whenAccels) {
			if (testType < kSpeedTest_testType_accel) {
				switch(testType) {
				case kSpeedTest_testType_speed:
					currentValue = Length(currentSpeed);
					break;
				case kSpeedTest_testType_speedX:
					currentValue = currentSpeed.x;
					break;
				case kSpeedTest_testType_speedY:
					currentValue = currentSpeed.y;
					break;
				case kSpeedTest_testType_speedZ:
					currentValue = currentSpeed.z;
					break;
				}
			} else if (testType == kSpeedTest_testType_steering) {
				float timeDif = float(currentTime - prevTime);
				if (timeDif <= 0.0f) continue; // no time difference
				float normFactor = Length(currentSpeed)*Length(prevSpeed);
				if (normFactor <= 0.0f) continue; // steering rate is not calculatable
				float vv = DotProd(currentSpeed,prevSpeed)/normFactor;
				float uu = 0.0;
				if (vv >= 1.0f) uu = 0.0;
				else if (vv <= -1.0f) uu = PI;
				else uu = acos(vv);
				currentValue = uu/timeDif;
			} else { // acceleration
				float timeDif = float(currentTime - prevTime);
				if (timeDif <= 0.0f) continue; // no time difference
				Point3 curAccel;
				switch(testType) {
				case kSpeedTest_testType_accel:
					currentValue = Length((currentSpeed - prevSpeed)/timeDif);
					break;
				case kSpeedTest_testType_accelX:
					currentValue = (currentSpeed.x - prevSpeed.x)/timeDif;	
					break;
				case kSpeedTest_testType_accelY:
					currentValue = (currentSpeed.y - prevSpeed.y)/timeDif;	
					break;
				case kSpeedTest_testType_accelZ:
					currentValue = (currentSpeed.z - prevSpeed.z)/timeDif;	
					break;
				}
				testValue /= TIME_TICKSPERSEC; // acceleration is per second squared
			}
			testSatisfied = (condType == kSpeedTest_conditionType_less) ?
								(currentValue < testValue) : (currentValue > testValue);
		} else {
			if (testType == kSpeedTest_testType_whenAccels) {
				testSatisfied = (Length(currentSpeed) > Length(prevSpeed));
			} else {
				testSatisfied = (Length(currentSpeed) < Length(prevSpeed));
			}
		}

		if (testSatisfied && exactStep) {
			testResult.Set(i);
			testTime[i] = 0.0f;
		}
	}

	return true;
}
Exemple #18
0
void SelectByChannel::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
{
	//TODO: Add the code for actually modifying the object

	//get th map id

	
//	TriObject *tobj = (TriObject*)os->obj;
//	Mesh &mesh = tobj->GetMesh();		

	Mesh *mesh = NULL;
	MNMesh *mnmesh = NULL;
		
	TriObject *collapsedtobj = NULL;
	if (os->obj->IsSubClassOf(triObjectClassID))
	{
		TriObject *tobj = (TriObject*)os->obj;
		mesh = &tobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(polyObjectClassID))
	{
		PolyObject *pobj = (PolyObject*)os->obj;
		mnmesh = &pobj->GetMesh();
	}



	int mapID;
	int subID;

	int selType;

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

	pblock->GetValue(pb_seltype,0,selType,FOREVER);

	if (subID < 0) subID = 0;
	if (subID > 2) subID = 2;
	
	
	if (mnmesh)
	{
		
		int numMaps = mnmesh->numm;

		mnmesh->dispFlags = MNDISP_VERTTICKS|MNDISP_SELVERTS ;
		mnmesh->selLevel = MNM_SL_VERTEX;

		if (mapID < numMaps)
		
		{
			UVVert *uvw = mnmesh->M(mapID)->v;
			MNMapFace *uvwFace = mnmesh->M(mapID)->f;
			if (uvw && uvwFace)
				
			{
				float *vsw = NULL;

				MNFace *face = mnmesh->f;

					

				vsw = mnmesh->getVSelectionWeights ();

				if (vsw == NULL)
				{
					mnmesh->SupportVSelectionWeights();
					vsw = mnmesh->getVSelectionWeights ();
				}

				BitArray processed;
				processed.SetSize(mnmesh->numv);
				processed.ClearAll();

				if (vsw && uvwFace && uvw)
				{
					if (selType == 0)
					{
						mnmesh->ClearVFlags (MN_SEL);
						for (int i = 0; i < mnmesh->numv; i++)
							vsw[i] = 0.0f;
					}

					for (int i = 0; i < mnmesh->numf; i++)
					{
						int deg = face[i].deg;
						for (int j = 0; j < deg; j++)
						{
							
							int index = uvwFace[i].tv[j];
							int gindex = face[i].vtx[j];
							if (!processed[gindex])
							{
								processed.Set(gindex);
								if (selType == 0)
								{	
									float w = uvw[index][subID];
									if (w >= 1.0f)
										mnmesh->v[gindex].SetFlag (MN_SEL);
//										mesh.vertSel.Set(gindex);
									else vsw[gindex] = uvw[index][subID];
								}
								else if (selType == 1)
								{	
									float w = uvw[index][subID];
									w += vsw[gindex];
									if (w >= 1.0f)
										mnmesh->v[gindex].SetFlag (MN_SEL);
//										mesh.vertSel.Set(gindex);
									else vsw[gindex] = uvw[index][subID];
								}
								else if (selType == 2)
								{	
									float w = uvw[index][subID];
									if (mnmesh->v[gindex].GetFlag (MN_SEL))//(mesh.vertSel[gindex])
										w = 1.0f - w;
									else w = vsw[gindex] - w;;
									if (w < 1.0f)
										mnmesh->v[gindex].ClearFlag (MN_SEL);
//										mesh.vertSel.Set(gindex,FALSE);
									vsw[gindex] = w;
								}
							}

						}
					}
				}
			}

		}
		
	}

	else if (mesh)
	{
		mesh->dispFlags = DISP_VERTTICKS|DISP_SELVERTS;
		mesh->selLevel = MESH_VERTEX;

		if (mesh->mapSupport(mapID))
		{
			UVVert *uvw = mesh->mapVerts(mapID);
			TVFace *uvwFace = mesh->mapFaces(mapID);	
			float *vsw = NULL;

			Face *face = mesh->faces;

				

			vsw = mesh->getVSelectionWeights ();

			if (vsw == NULL)
			{
				mesh->SupportVSelectionWeights();
				vsw = mesh->getVSelectionWeights ();
			}

			BitArray processed;
			processed.SetSize(mesh->numVerts);
			processed.ClearAll();

			if (vsw && uvwFace && uvw)
			{
				if (selType == 0)
				{
					mesh->vertSel.ClearAll();
					for (int i = 0; i < mesh->numVerts; i++)
						vsw[i] = 0.0f;
				}

				for (int i = 0; i < mesh->numFaces; i++)
				{
					for (int j = 0; j < 3; j++)
					{
						
						int index = uvwFace[i].t[j];
						int gindex = face[i].v[j];
						if (!processed[gindex])
						{
							processed.Set(gindex);
							if (selType == 0)
							{	
								float w = uvw[index][subID];
								if (w >= 1.0f)
									mesh->vertSel.Set(gindex);
								else vsw[gindex] = uvw[index][subID];
							}
							else if (selType == 1)
							{	
								float w = uvw[index][subID];
								w += vsw[gindex];
								if (w >= 1.0f)
									mesh->vertSel.Set(gindex);
								else vsw[gindex] = uvw[index][subID];
							}
							else if (selType == 2)
							{	
								float w = uvw[index][subID];
								if (mesh->vertSel[gindex])
									w = 1.0f - w;
								else w = vsw[gindex] - w;;
								if (w < 1.0f)
									mesh->vertSel.Set(gindex,FALSE);
								vsw[gindex] = w;
							}
						}

					}
				}
			}

		}
	}
	


	Interval iv;
	iv = FOREVER;

	os->obj->PointsWereChanged();

	iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,SELECT_CHAN_NUM);

	os->obj->UpdateValidity (SELECT_CHAN_NUM, iv);


}
Exemple #19
0
IGeometryChecker::ReturnVal MultipleEdgeChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val)
{
	val.mIndex.ZeroCount();
	if(IsSupported(nodeToCheck))
	{
		LARGE_INTEGER	ups,startTime;
		QueryPerformanceFrequency(&ups);
		QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog 
		bool compute = true;
		bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active!
		ObjectState os  = nodeToCheck->EvalWorldState(t);
		Object *obj = os.obj;
		BitArray arrayOfEdges; //we fill this up with the verts, if not empty then we have isolated vets
		EdgeFaceList edgeList;
		if(os.obj->IsSubClassOf(triObjectClassID))
		{
			TriObject *tri = dynamic_cast<TriObject *>(os.obj);
			if(tri)
			{
				Mesh &mesh = tri->GetMesh();
				edgeList.CreateEdgeFaceList(mesh);
				if(checkTime)
				{
					DialogChecker::Check(checkTime,compute,mesh.numFaces,startTime,ups);
					if(compute==false)
						return IGeometryChecker::eFail;
				}
				arrayOfEdges.SetSize(CheckerMeshEdge::GetTotalNumEdges(mesh.numFaces));
				arrayOfEdges.ClearAll();
			}
			else return IGeometryChecker::eFail;
		}
		else if(os.obj->IsSubClassOf(polyObjectClassID))
		{
			PolyObject *poly = dynamic_cast<PolyObject *>(os.obj);
			if(poly)
			{
				MNMesh &mnMesh = poly->GetMesh();
				edgeList.CreateEdgeFaceList(mnMesh);
				if(checkTime)
				{
					DialogChecker::Check(checkTime,compute,mnMesh.numf,startTime,ups);
					if(compute==false)
						return IGeometryChecker::eFail;
				}
				arrayOfEdges.SetSize(mnMesh.nume);
				arrayOfEdges.ClearAll();
			}
			else return IGeometryChecker::eFail;
		}
		#pragma omp parallel for
		for(int i=0;i<edgeList.mNumVertexEdges;++i)
		{
			for(int j=0;j<edgeList.mVertexEdges[i]->mEdges.Count();++j)
			{
				EdgeFaceList::Edge *localEdge = edgeList.mVertexEdges[i]->mEdges[j];
				if(localEdge)
				{
					if(localEdge->mFaces.Count()>2)
					{
						#pragma omp critical
						{
							arrayOfEdges.Set(localEdge->mEdgeNum);
						}
					}
				}
			}
		}
		if(arrayOfEdges.IsEmpty()==false) //we have an isolated vierts
		{
			int localsize= arrayOfEdges.GetSize();
			for(int i=0;i<localsize;++i)
			{
				if(arrayOfEdges[i])
					val.mIndex.Append(1,&i);
			}
		}
		return TypeReturned();
	}
	return IGeometryChecker::eFail;
}
Exemple #20
0
void RenderMesh::ConvertFaces(Mesh *Mesh, int MatIndex, Tab<Vert3> &Verts, Tab<Face3> &Faces, bool NegScale)
{
    Face3			TmpFace;
    Vert3			TmpVert;
	BitArray		Written;
	int				i,j,k,NumFace;
	int				NumUV,UVCount,Index;
	int				NumVert,Count,VIndex;
	Face			*aFace;
	Tab<BasisVert>	FNormals;
	Tab<VNormal>	Normals;
	UVVert			*UVVert;
	TVFace			*UVFace;
	Point3			S,T,SxT;
	unsigned long	Sg;

	bool useMeshNorms = false;


	if(NegScale)
	{
		gVIndex[0] = 2;
		gVIndex[1] = 1;
		gVIndex[2] = 0;
	}
	else
	{
		gVIndex[0] = 0;
		gVIndex[1] = 1;
		gVIndex[2] = 2;
	}

	// Do we have an EditNormal modifier present - if so we use those normals instead.
	// We only use this if they have been applied on a face with smoothing groups, otherwise
	// it messes up the tangent space calculation.  Probably not the most obtmized route, but it
	// works...

	MeshNormalSpec * meshNorm = Mesh->GetSpecifiedNormals();
	if(meshNorm && meshNorm->GetNumNormals())
		useMeshNorms = true;

	NumFace = 0;

	for(i=0; i < Mesh->getNumFaces(); i++) 
	{
		if(!Mesh->faces[i].Hidden())
		{
			Index = Mesh->getFaceMtlIndex(i) + 1;

			if(Index == MatIndex || MatIndex == 0)
			{
				NumFace++;
			}
		}

	}

	NumVert = Mesh->getNumVerts();
    Verts.SetCount(NumVert);

    Faces.SetCount(NumFace);

	if(NumVert == 0 || NumFace == 0)
	{
		return;
	}

	ComputeVertexNormals(Mesh,FNormals,Normals,NegScale);

    Written.SetSize(Mesh->getNumVerts());
    Written.ClearAll();

	NumUV = Mesh->getNumMaps();	

	if(NumUV)
	{	
		Count = 0;

		if(NumUV > MAX_TMUS + 1)
		{
			NumUV = MAX_TMUS + 1;
		}

		for(i=0; i < Mesh->getNumFaces(); i++) 
		{
			aFace = &Mesh->faces[i];

			TmpFace.m_Num[0] = aFace->v[gVIndex[0]];
			TmpFace.m_Num[1] = aFace->v[gVIndex[1]];
			TmpFace.m_Num[2] = aFace->v[gVIndex[2]];


			Sg = aFace->smGroup;

			for(j=0; j < 3; j++) 
			{
				VIndex			 = aFace->v[gVIndex[j]];
				TmpVert.m_Pos	 = Mesh->verts[VIndex];

				if(Sg)
				{
					if(useMeshNorms)
					{
						int normID = meshNorm->Face(i).GetNormalID(gVIndex[j]);
						TmpVert.m_Normal = meshNorm->Normal(normID).Normalize();
						Normals[VIndex].GetNormal(Sg,S,T,SxT);
					}
					else
					        TmpVert.m_Normal = Normals[VIndex].GetNormal(Sg,S,T,SxT);
					
					TmpVert.m_S		 = S;
					TmpVert.m_T		 = T;
					TmpVert.m_SxT	 = SxT;

				}
				else
				{
					TmpVert.m_Normal = FNormals[i].m_Normal;
					TmpVert.m_S		 = FNormals[i].m_S;
					TmpVert.m_T		 = FNormals[i].m_T;
					TmpVert.m_SxT	 = FNormals[i].m_SxT;
				}

				UVCount		 = 0;
				TmpVert.m_Sg = Sg;

				for(k=0;k<m_MapChannels.Count();k++)
				{	
					int index = m_MapChannels[k];

					if(Mesh->getNumMapVerts(index))
					{
						UVVert = Mesh->mapVerts(index);
						UVFace = Mesh->mapFaces(index);

						TmpVert.m_UV[k].x = UVVert[UVFace[i].t[gVIndex[j]]].x;
						TmpVert.m_UV[k].y = UVVert[UVFace[i].t[gVIndex[j]]].y;

	
					}
					else
					{
						TmpVert.m_UV[k].x = 0.0f;
						TmpVert.m_UV[k].y = 0.0f;
					}
				}
				
		
				if(Written[VIndex]) 
				{
					if((Sg == 0) || 
					   (Verts[VIndex].m_Sg != TmpVert.m_Sg) ||	
					   (!UVVertEqual(Verts[VIndex].m_UV[0],TmpVert.m_UV[0]))) 
					{
						TmpFace.m_Num[j] = Verts.Count();
						Verts.Append(1,&TmpVert,10);
					}
				} 
				else 
				{
					Verts[VIndex] = TmpVert;
					Written.Set(VIndex);
				}

			}

			if(!Mesh->faces[i].Hidden())
			{
				Index = Mesh->getFaceMtlIndex(i) + 1;

				if(Index == MatIndex || MatIndex == 0)
				{
					Faces[Count++] = TmpFace;
				}

			}

		}

	}
	else
	{
		for(i=0; i < Mesh->getNumFaces(); i++) 
		{
			aFace = &Mesh->faces[i];

			Faces[i].m_Num[0] = aFace->v[gVIndex[0]];
			Faces[i].m_Num[1] = aFace->v[gVIndex[1]];
			Faces[i].m_Num[2] = aFace->v[gVIndex[2]];

			for(j=0; j < 3; j++) 
			{
				VIndex					= aFace->v[gVIndex[j]];
				Verts[VIndex].m_Pos		= Mesh->verts[VIndex];
				Verts[VIndex].m_Normal	= Normals[VIndex].GetNormal(aFace->smGroup,S,T,SxT);
				Verts[VIndex].m_S		= Point3(0.0f,0.0f,0.0f);
				Verts[VIndex].m_T		= Point3(0.0f,0.0f,0.0f);
				Verts[VIndex].m_SxT		= Point3(0.0f,0.0f,0.0f);

				for(k=0; k < MAX_TMUS; k++)
				{
					Verts[VIndex].m_UV[k].x = 0.0f;
					Verts[VIndex].m_UV[k].y = 0.0f;
				}

			}

		}

	}
	Verts.Shrink();
	

}
Exemple #21
0
/////////////////////////////////////////////////////////////////////
// Note: 
//    The vertex color data that is used by the ModifyPolyObject 
//    method was created based on this PolyObject's displayed 
//    TriMesh (Mesh). This data is mapped back to the original 
//    PolyMesh (MNMesh).  The mapping relies on the same process 
//    that was used by the method MNMesh::OutToTri() to generate 
//    the Mesh.
// Warning:
//    The mapping used in this method will need to be updated if 
//    anything changes in the way MNMesh generates its displayed Mesh.
// Author: 
//    Wayne Catalfano
// Date:
//    August 30, 2000
//
///////////////////////////////////////////////////////////////////////
void ApplyVCMod::ModifyPolyObject(PolyObject* pPolyObj, TimeValue t)
{
	static int calls = 0;
	iValid = FOREVER;
	Interval valid = GetValidity(t);

	MNMesh& mesh = pPolyObj->GetMesh();
	if (mesh.MNum() < 1) mesh.SetMapNum (1);

	// get the vertex color map
	MNMap* pVCMap = mesh.M(0);

	// initialize to an all white map if necessary
	if (pVCMap->GetFlag(MN_DEAD)) mesh.InitMap(0);

	if (mixedVertexColors.Count() > 0) {
		pVCMap->setNumVerts (mesh.VNum());
		pVCMap->setNumFaces (mesh.FNum());

		// MNMesh keeps the vertices in the same order when it creates
		// the Mesh.  The Mesh vertices Map directly back to the MNMesh
		// vertices in the same order.
		for (int i=0; i<mesh.VNum(); i++) {
			pVCMap->v[i] = i<mixedVertexColors.Count() ?
				Point3(mixedVertexColors[i]->r, mixedVertexColors[i]->g, mixedVertexColors[i]->b) :
				Point3(1.0f, 1.0f, 1.0f);
		}

		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			pVCMap->F(i)->SetSize(mesh.F(i)->deg);
			for (int j=0; j<mesh.F(i)->deg;++j) {
				pVCMap->F(i)->tv[j] = mesh.F(i)->vtx[j];
			}
		}
	}
	else if (faceColors.Count() > 0) {
		int numVCVerts = 0;
		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			numVCVerts += mesh.F(i)->deg;
		}
		pVCMap->setNumVerts (numVCVerts);
		pVCMap->setNumFaces (mesh.FNum());

		// This mapping process mimicks the process used to generate  
		// the Mesh in the method MNMesh::OutToTri().
		int faceVert = 0;
		int triFaceIndx = 0;
		BitArray faceVertSet;
		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			pVCMap->F(i)->SetSize(mesh.F(i)->deg);
			faceVertSet.SetSize(mesh.F(i)->deg);
			faceVertSet.ClearAll();
			int tnum = mesh.F(i)->TriNum()*3;
			Tab<int> triVerts;
			// The method MNFace::GetTriangles is at the heart of the 
			// process used to map Mesh triangles back to MNMesh faces.
			mesh.F(i)->GetTriangles (triVerts);
			for (int j=0; j<tnum; j+=3) {
				for (int k=0; k<3; ++k) {
					int vertIndex = triVerts[j+k];
					// check if we already added a vert for this index
					if (!faceVertSet[vertIndex]) {
						pVCMap->v[faceVert] = triFaceIndx<faceColors.Count() ? 
							Point3(faceColors[triFaceIndx]->colors[k].r, 
								   faceColors[triFaceIndx]->colors[k].g, 
								   faceColors[triFaceIndx]->colors[k].b) :
							Point3(1.0f, 1.0f, 1.0f);

						pVCMap->F(i)->tv[vertIndex] = faceVert;
						faceVertSet.Set(vertIndex);
						faceVert++; 
					}
				}
				++triFaceIndx;
			}
		}
	}

	NotifyDependents(Interval(t,t), PART_VERTCOLOR & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE);
	NotifyDependents(Interval(t,t), PART_TOPO & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE);
	pPolyObj->UpdateValidity(VERT_COLOR_CHAN_NUM, valid);
}
void PatchDeformPW::BuildParamData(Object *obj, LocalPatchData *localData,PatchMesh *patch,Matrix3 patchTM,Matrix3 baseTM)
	{
	localData->numPatches = patch->numPatches;
//put our base mesh data into patch space
	Matrix3 tmFromBaseToPatch = baseTM * Inverse(patchTM);

	Matrix3 tmFromPatchToBase = patchTM * Inverse(baseTM);

	Tab<Point3> pointData;
	int pointCount = obj->NumPoints();
	pointData.SetCount(pointCount);

	Tab<int> closestPoint;
	closestPoint.SetCount(pointCount);

	localData->paramData.SetCount(pointCount);

	for (int i = 0; i < pointCount; i++)
		{
		Point3 p = obj->GetPoint(i);
		localData->paramData[i].initialLocalPoint = p;
		p = p * tmFromBaseToPatch;
		pointData[i] = p;
		closestPoint[i] = -1;
		}

	int numPatches = patch->numPatches;

//split the patches into 10x10 chunks
	Tab<Point3> patchPoints;
	patchPoints.SetCount(numPatches * 100);


	int ct = 0;
	for (int i = 0; i < numPatches; i++)
		{
		Patch *p = &patch->patches[i];

		if (p->type == PATCH_QUAD)
			{
			float u,v;
			float inc = 1.0f/(10.0f+1.0f);
			u = inc;
			v = inc;
			for (int y = 0; y < 10; y++)
				{
				u = inc;
				for (int x = 0; x < 10; x++)
					{
					Point3 pt = p->interp(patch, u, v);
					patchPoints[ct] = pt;
					ct++;
					u += inc;
					}
				v += inc;
				}

			}
		else ct += 100;
		}

	for (int i = 0; i < pointCount; i++)
		{
		int closest = -1;
		float d= 0.0f;
		for (int j = 0; j <  ct; j++)
			{
			float len = LengthSquared(patchPoints[j]-pointData[i]);
			if ((closest == -1) || (len<d))
				{
				d = len;
				closest = j;
				}
			}
		closestPoint[i] = closest/100;		
		}

	BitArray usedPatches;
	usedPatches.SetSize(numPatches);
	usedPatches.ClearAll();
	for (int i = 0; i < pointCount; i++)
		{
		usedPatches.Set(closestPoint[i]);
		}

	int sampleRate;
	Interval iv;
	iv = FOREVER;

	pblock->GetValue(pb_samplerate,0,sampleRate,iv);
	patchPoints.SetCount(sampleRate*sampleRate);

	

	for (int i = 0; i < numPatches; i++)
		{
		Patch *p = &patch->patches[i];

		if (ip)
			{
			TSTR name;
			name.printf(GetString(IDS_COMPLETED_PCT),(float) i / numPatches *100.0f);
			SetWindowText(GetDlgItem(hWnd,IDC_STATUS),name);
			}

		float inc = 1.0f/(sampleRate+1.0f);

		if ( (usedPatches[i]) && (p->type == PATCH_QUAD))
			{
			float u,v;
			
			u = inc;
			v = inc;
			ct = 0;
			for (int y = 0; y < sampleRate; y++)
				{
				u = inc;
				for (int x = 0; x < sampleRate; x++)
					{
					Point3 pt = p->interp(patch, u, v);
					patchPoints[ct] = pt;
					ct++;
					u += inc;
					}
				v += inc;
				}

			
			for (int j = 0; j < pointCount; j++)
				{

				if ((ip) && ((j%10) == 0))
					{
					TSTR name;
					name.printf(GetString(IDS_COMPLETED_PCT_W_COUNT),(float) i / numPatches *100.0f,j,pointCount);
					SetWindowText(GetDlgItem(hWnd,IDC_STATUS),name);
					}
				if (closestPoint[j] == i)
					{
					int closest = -1;
					float d= 0.0f;

					for (int k = 0; k <  sampleRate*sampleRate; k++)
						{
						float len = LengthSquared(patchPoints[k]-pointData[j]);
						if ((closest == -1) || (len<d))
							{
							d = len;
							closest = k;							
							}
						}	
					
					localData->paramData[j].uv.y = float (closest/sampleRate);
					localData->paramData[j].uv.x = float (closest - (localData->paramData[j].uv.y*sampleRate));

					localData->paramData[j].uv.y = (localData->paramData[j].uv.y +1) * inc;
					localData->paramData[j].uv.x = (localData->paramData[j].uv.x +1) * inc;		
					localData->paramData[j].patchIndex = i;

//get the u vec
					float u = localData->paramData[j].uv.x;
					float v = localData->paramData[j].uv.y;
					float delta = 1.0f/(sampleRate+1.0f)*0.5f;
					float du = u-delta;
					float dv = v-delta;

if (du <= 0.0f) DebugPrint(_T("error du 0.0f \n"));
if (dv <= 0.0f) DebugPrint(_T("error dv 0.0f \n"));
if (du >= 1.0f) DebugPrint(_T("error du 1.0f \n"));
if (dv >= 1.0f) DebugPrint(_T("error dv 1.0f \n"));

					localData->incDelta = delta;

					Patch *p = &patch->patches[i];

					Point3 uVec = Normalize(p->interp(patch, du, v)-patchPoints[closest]);
//get the v vec
					Point3 vVec = Normalize(p->interp(patch, u, dv)-patchPoints[closest]);

					Point3 xAxis,yAxis,zAxis;
					xAxis = uVec;
					zAxis = CrossProd(uVec,vVec);
					yAxis = CrossProd(xAxis,zAxis);

					Point3 center = patchPoints[closest];

					Matrix3 tm(xAxis,yAxis,zAxis,center);
/*DebugPrint(_T("init %d\n"),j);*/
/*DebugPrint(_T("%f %f %f\n"),xAxis.x,xAxis.y,xAxis.z);
DebugPrint(_T("%f %f %f\n"),yAxis.x,yAxis.y,yAxis.z);
DebugPrint(_T("%f %f %f\n"),zAxis.x,zAxis.y,zAxis.z);
DebugPrint(_T("%f %f %f\n"),center.x,center.y,center.z);*/

					localData->paramData[j].initialPoint = pointData[j]*Inverse(tm);
//DebugPrint(_T("init %d\n"),j);

					}
				}
			
			}
		}

	if (ip)
		{
		TSTR name;
		name.printf(_T("%s"),GetString(IDS_PICK));
		SetWindowText(GetDlgItem(hWnd,IDC_STATUS),name);
		}

//split the patch into sub samples chunk
	}
IGeometryChecker::ReturnVal MissingUVCoordinatesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val)
{
	val.mIndex.ZeroCount();
	if(IsSupported(nodeToCheck))
	{
		LARGE_INTEGER	ups,startTime;
		QueryPerformanceFrequency(&ups);
		QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog 
		bool compute = true;
		bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active!
		UVWChannel uvmesh;
		ObjectState os  = nodeToCheck->EvalWorldState(t);
		Object *obj = os.obj;
		if(os.obj->IsSubClassOf(triObjectClassID))
		{
			TriObject *tri = dynamic_cast<TriObject *>(os.obj);
			if(tri)
			{
				BitArray arrayOfVertices;
				arrayOfVertices.SetSize(tri->mesh.numVerts);
				arrayOfVertices.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels = tri->mesh.getNumMaps();
				int index;
				for(int i=0;i<numChannels;++i)
				{
					if(tri->mesh.mapSupport(i))
					{

						MeshMap *map  = &tri->mesh.Map(i);
						if(map->getNumVerts()>0 &&map->getNumFaces()>0)
						{
							returnval= TypeReturned();
							int numFaces = map->getNumFaces();
							TVFace * tvFaces = map->tf;
							UVVert *  uvVerts= map->tv;
						
							#pragma omp parallel for
							for(int faceIndex =0;faceIndex<numFaces;++faceIndex)
							{
								if(compute)
								{
									TVFace& tvFace = tvFaces[faceIndex];
									Point3 tv = uvVerts[tvFace.t[0]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[0];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									tv = uvVerts[tvFace.t[1]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[1];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									tv = uvVerts[tvFace.t[2]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[2];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									if(checkTime==true)
									{
										#pragma omp critical
										{
											DialogChecker::Check(checkTime,compute,numFaces,startTime,ups);
										}
									}
								}
							}
						}
					}
				}
				if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfVertices.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfVertices[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
		else if(os.obj->IsSubClassOf(polyObjectClassID))
		{
			PolyObject *poly = dynamic_cast<PolyObject *>(os.obj);
			if(poly)
			{
				BitArray arrayOfVertices;
				arrayOfVertices.SetSize(poly->GetMesh().numv);
				arrayOfVertices.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels= poly->GetMesh().MNum();
				int index;
				for(int i=0;i<numChannels;++i)
				{
					if(poly->GetMesh().M(i))
					{
						MNMesh *mesh = &(poly->GetMesh());
						MNMap *mnmap = mesh->M(i);
						if(mnmap&&mnmap->numv>0&&mnmap->numf>0)
						{
							returnval= TypeReturned();
							int numFaces = mnmap->numf;
							#pragma omp parallel for
							for(int faceIndex =0;faceIndex<numFaces;++faceIndex)
							{
								if(compute)
								{
									Point3 tv;
									int a,b,c;
									MNMapFace *face = mnmap->F(faceIndex);
									UVVert *  uvVerts=  mnmap->v;
									for(int j=0;j<(face->deg);++j)
									{
										if(j==(face->deg-2))
										{
											a  = j; b = j+1; c = 0;
										}
										else if(j==(face->deg-1))
										{
											a  = j; b = 0; c = 1;
										}
										else
										{
											a  = j; b = j+1; c = j+2;
										}
										tv = uvVerts[face->tv[a]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[a];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										tv = uvVerts[face->tv[b]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[b];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										tv = uvVerts[face->tv[c]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[c];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										if(checkTime==true)
										{
											#pragma omp critical
											{
												DialogChecker::Check(checkTime,compute,numFaces,startTime,ups);
											}
										}
									}
								}
							}	
						}
					}
				}
				if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfVertices.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfVertices[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
	}
	return IGeometryChecker::eFail;
}
Exemple #24
0
void UnwrapMod::BuildInitialMapping(Mesh *msh)
	{
//build bounding box
	Box3 bbox;
	bbox.Init();
//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
		{
		int pcount = 3;
//	if (TVMaps.f[i].flags & FLAG_QUAD)
		pcount = TVMaps.f[i]->count;
		for (int j = 0; j < pcount; j++)
			{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
			}

		}
	Tab<int> indexList;

	indexList.SetCount(TVMaps.f.Count() *4);
	BitArray usedIndex;
	usedIndex.SetSize(TVMaps.f.Count() *4);
	usedIndex.ClearAll();

	for (i = 0; i < TVMaps.f.Count()*4; i++)
		indexList[i] = -1;

	for (i = 0; i < TVMaps.f.Count(); i++)
		{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
			{
			int pcount = 3;
//		if (TVMaps.f[i].flags & FLAG_QUAD) pcount = 4;
			pcount = TVMaps.f[i]->count;
			for (int j = 0; j < pcount; j++)
				{
				usedIndex.Set(msh->faces[i].v[j]);
				}
			}

		}

	int ct = 0;
	for (i = 0; i < usedIndex.GetSize(); i++)
		{
		if (usedIndex[i])
			indexList[i] = ct++;

		}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	TVMaps.cont.SetCount(usedIndex.NumberSet());
	vsel.SetSize(usedIndex.NumberSet());

//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (i = 0; i < TVMaps.f.Count(); i++)
		{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
			{
			int pcount = 3;
//		if (TVMaps.f[i].flags & FLAG_QUAD)	pcount = 4;
			pcount = TVMaps.f[i]->count;
			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
				{
				int index;
				int a = msh->faces[i].v[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				TVMaps.v[index].p.x =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f;
				TVMaps.v[index].p.y =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f;
				TVMaps.v[index].p.z =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f;
				TVMaps.v[index].influence =  0.f;
				TVMaps.v[index].flags =  0.f;
				TVMaps.cont[index] = NULL;
		
				}

			}
		}

	}
Exemple #25
0
void UnwrapMod::CopySelectionMesh(ObjectState *os, ModContext &mc, int CurrentChannel, TimeValue t)
	{	

		objType = IS_MESH;
		TriObject *tobj = (TriObject*)os->obj;
		MeshTopoData *d  = (MeshTopoData*)mc.localData;
		if (!d) 
			{
			mc.localData = d = new MeshTopoData(tobj->GetMesh());
			d->SetFaceSel(tobj->GetMesh().faceSel, this, t);
			UpdateFaceSelection(d->faceSel);
			

			}
		if ( ((editMod==this) && (!d->GetMesh())) || (updateCache))
			{
			d->SetCache(tobj->GetMesh());
			d->SetFaceSel(tobj->GetMesh().faceSel, this, t);
			updateCache = FALSE;
			UpdateFaceSelection(d->faceSel);
			SyncTVToGeomSelection(d);

			hiddenPolygons.SetSize(tobj->GetMesh().getNumFaces());
			hiddenPolygons.ClearAll();
			for (int i = 0; i < tobj->GetMesh().getNumFaces(); i++)
				{
				if (tobj->GetMesh().faces[i].Hidden())
					hiddenPolygons.Set(i,TRUE);
				}
			}

		BitArray faceSel = d->faceSel;


		faceSel.SetSize(tobj->GetMesh().getNumFaces(),TRUE);

		if ( (ip && (ip->GetSubObjectLevel() > 0) ))
			{

			tobj->GetMesh().faceSel = faceSel;

			if (showVerts)
				{
//select verts based on the current tverts;
				BitArray vertSel;
				vertSel.SetSize(tobj->GetMesh().getNumVerts(),TRUE);
				vertSel.ClearAll();
				for(int sv = 0; sv < TVMaps.f.Count();sv++)
					{
					if (!(TVMaps.f[sv]->flags & FLAG_DEAD))
						{
						int pcount = 3;
//						if (TVMaps.f[sv].flags & FLAG_QUAD) pcount = 4;
						pcount = TVMaps.f[sv]->count;
						for (int j = 0; j < pcount ; j++)
							{
							int index = TVMaps.f[sv]->t[j];
//6-29--99 watje
							if ((index < vsel.GetSize()) && (vsel[index] ==1) && (sv<tobj->GetMesh().numFaces))
//							if (vsel[index] ==1)
								{
								int findex = tobj->GetMesh().faces[sv].v[j];
//6-29--99 watje
								if ((findex < vertSel.GetSize()) && (findex >=0))
									vertSel.Set(findex,1);
								}
							}
						}
					}
				tobj->GetMesh().vertSel = vertSel;
				tobj->GetMesh().SetDispFlag(DISP_SELFACES|DISP_VERTTICKS|DISP_SELVERTS);
//done++;
				}
			else
				{
				tobj->GetMesh().SetDispFlag(DISP_SELFACES);
				}

//UNFOLD STUFF
			Face *faces = tobj->GetMesh().faces;
			for (int i =0; i < tobj->GetMesh().getNumFaces(); i++)
				{
				if ( (i < hiddenPolygons.GetSize()) && (hiddenPolygons[i]) ) 
					faces[i].Hide();
				else faces[i].Show();
				}

			}

		
		if (!tmControl || (flags&CONTROL_OP) || (flags&CONTROL_INITPARAMS)) 
			InitControl(t);


//if planar mode build vert and face list

		if ( (ip && (ip->GetSubObjectLevel() == 1) ))
			{
			MeshUpdateGData(&tobj->GetMesh(),faceSel);
	
			}

	}
Exemple #26
0
void	UnwrapMod::fnUnfoldSelectedPolygons(int unfoldMethod, BOOL normalize)
	{		
// flatten selected polygons
	BailStart();
	BitArray *polySel = fnGetSelectedPolygons();
	BitArray holdPolySel;
	if (polySel == NULL) 
		return;
	if (TVMaps.f.Count() == 0) return;


	if (!theHold.Holding())
		{
		theHold.SuperBegin();
		theHold.Begin();
		}

	holdPolySel.SetSize(polySel->GetSize());
	holdPolySel = *polySel;

	HoldPointsAndFaces();	

	Point3 normal(0.0f,0.0f,1.0f);

	BitArray oldSel = *fnGetSelectedPolygons();

	Tab<Point3> mapNormal;
	mapNormal.SetCount(0);

	BOOL bContinue = BuildCluster( mapNormal, 5.0f, TRUE, TRUE);
	TSTR statusMessage;

	BitArray sel;
	sel.SetSize(TVMaps.f.Count());

	if (bContinue)
		{
			
		for (int i =0; i < clusterList.Count(); i++)
			{
			sel.ClearAll();
			for (int j = 0; j < clusterList[i]->faces.Count();j++)
				sel.Set(clusterList[i]->faces[j]);
			fnSelectPolygonsUpdate(&sel, FALSE);
			PlanarMapNoScale(clusterList[i]->normal);

			int per = (i * 100)/clusterList.Count();
			statusMessage.printf("%s %d%%.",GetString(IDS_PW_STATUS_MAPPING),per);
			if (Bail(ip,statusMessage))
				{
				i = clusterList.Count();
				bContinue =  FALSE;
				}

			}


		if ( (bContinue) && (clusterList.Count() > 1) )
			{

			if (!ip) return;
			ModContextList mcList;		
			INodeTab nodes;
			ip->GetModContexts(mcList,nodes);

			int objects = mcList.Count();

			MeshTopoData *md = (MeshTopoData*)mcList[0]->localData;

			if (md == NULL) 
				{
				theHold.Cancel();
				theHold.SuperCancel();
				return;
				}

			Tab<Point3> objNormList;
			BuildNormals(md,objNormList);

//remove internal edges
			BitArray *selectedPolygons = fnGetSelectedPolygons();
			Tab<int> clusterGroups;
			clusterGroups.SetCount(TVMaps.f.Count());
			for (i =0; i < clusterGroups.Count(); i++)
				{
				clusterGroups[i] = -1;
				}
		//loop through all tagged edges and remove any that onely have one edhes selected
			for (i = 0; i < clusterList.Count(); i++)
				{
				for (int j = 0; j < clusterList[i]->faces.Count(); j++)
					{
					int faceIndex = clusterList[i]->faces[j];
					clusterGroups[faceIndex] = i;
					}
				}
			BitArray processedClusters;
			processedClusters.SetSize(clusterList.Count());
			processedClusters.ClearAll();

			Tab<BorderClass> edgesToBeProcessed;

			BOOL done = FALSE;
			int currentCluster = 0;

			processedClusters.Set(0);
			clusterList[0]->newX = 0.0f;
			clusterList[0]->newY = 0.0f;
//		clusterList[0]->angle = 0.0f;
			for (int i = 0; i < clusterList[0]->borderData.Count(); i++)
				{
				int outerFaceIndex = clusterList[0]->borderData[i].outerFace;
				int connectedClusterIndex = clusterGroups[outerFaceIndex];
				if ((connectedClusterIndex != 0) && (connectedClusterIndex != -1))
					{
					edgesToBeProcessed.Append(1,&clusterList[0]->borderData[i]);
					}
				}
			BitArray seedFaceList;
			seedFaceList.SetSize(clusterGroups.Count());
			seedFaceList.ClearAll();
			for (i = 0; i < seedFaces.Count(); i++)
				{
				seedFaceList.Set(seedFaces[i]);
				}

			while (!done)
				{
				Tab<int> clustersJustProcessed;
				clustersJustProcessed.ZeroCount();
				done = TRUE;

				int edgeToAlign = -1;
				float angDist = PI*2;
				if (unfoldMethod == 1)
					angDist =  PI*2;
				else if (unfoldMethod == 2) angDist = 0;
				for (i = 0; i < edgesToBeProcessed.Count(); i++)
					{
					int outerFace = edgesToBeProcessed[i].outerFace;
					int connectedClusterIndex = clusterGroups[outerFace];
					if (!processedClusters[connectedClusterIndex])
						{
						int innerFaceIndex = edgesToBeProcessed[i].innerFace;
						int outerFaceIndex = edgesToBeProcessed[i].outerFace;
//get angle
						Point3 innerNorm, outerNorm;
						innerNorm = objNormList[innerFaceIndex];
						outerNorm = objNormList[outerFaceIndex];
						float dot = DotProd(innerNorm,outerNorm);

						float angle = 0.0f;

						if (dot == -1.0f)
							angle = PI;
						else if (dot == 1.0f)
							angle = 0.f;						
						else angle = acos(dot);

						if (unfoldMethod == 1)
							{
							if (seedFaceList[outerFaceIndex])
								angle = 0.0f;
							if (angle < angDist)
								{
								angDist = angle;
								edgeToAlign = i;
								}
							}

						else if (unfoldMethod == 2)
							{
							if (seedFaceList[outerFaceIndex])
								angle = 180.0f;
							if (angle > angDist)
								{
								angDist = angle;
								edgeToAlign = i;
								}
							}

						}
					}
				if (edgeToAlign != -1)
					{
					int innerFaceIndex = edgesToBeProcessed[edgeToAlign].innerFace;
					int outerFaceIndex = edgesToBeProcessed[edgeToAlign].outerFace;
					int edgeIndex = edgesToBeProcessed[edgeToAlign].edge;
					

					int connectedClusterIndex = clusterGroups[outerFaceIndex];

					seedFaceList.Set(outerFaceIndex, FALSE);

					processedClusters.Set(connectedClusterIndex);
					clustersJustProcessed.Append(1,&connectedClusterIndex);
					AlignCluster(i,connectedClusterIndex,innerFaceIndex, outerFaceIndex,edgeIndex);
					done = FALSE;
					}

//build new cluster list
				for (int j = 0; j < clustersJustProcessed.Count(); j++)
					{
					int clusterIndex = clustersJustProcessed[j];
					for (int i = 0; i < clusterList[clusterIndex]->borderData.Count(); i++)
						{
						int outerFaceIndex = clusterList[clusterIndex]->borderData[i].outerFace;
						int connectedClusterIndex = clusterGroups[outerFaceIndex];
						if ((!processedClusters[connectedClusterIndex]) && (connectedClusterIndex != 0) && (connectedClusterIndex != -1))
							{
							edgesToBeProcessed.Append(1,&clusterList[clusterIndex]->borderData[i]);
							}
						}
					}
				}
			}

		vsel.SetSize(TVMaps.v.Count());
		vsel.ClearAll();
		for (i = 0; i < clusterList.Count(); i++)
			{
			for (int j =0; j < clusterList[i]->faces.Count(); j++)
				{
				int faceIndex = clusterList[i]->faces[j];
				for (int k =0; k < TVMaps.f[faceIndex]->count; k++)
					{
					int vertexIndex = TVMaps.f[faceIndex]->t[k];
					vsel.Set(vertexIndex);
					}
				}
			}
//now weld the verts
		if (normalize)
			{
			NormalizeCluster();
			}

		float tempWeld = weldThreshold;
		weldThreshold = 0.001f;
		WeldSelected(FALSE);
		weldThreshold = tempWeld;


		}

	


	FreeClusterList();

	if (bContinue)
		{	
		theHold.Accept(_T(GetString(IDS_PW_PLANARMAP)));
		theHold.SuperAccept(_T(GetString(IDS_PW_PLANARMAP)));

		fnSelectPolygonsUpdate(&holdPolySel, FALSE);
		theHold.Suspend();
		fnSyncTVSelection();
		theHold.Resume();
		}
	else
		{
		theHold.Cancel();
		theHold.SuperCancel();
		}

	RebuildEdges();

	theHold.Suspend();
	fnSyncGeomSelection();
	theHold.Resume();


	NotifyDependents(FOREVER,PART_SELECT,REFMSG_CHANGE);
	InvalidateView();


	}
	void	UnwrapMod::CleanUpDeadVertices()
	{

		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			BitArray usedList;


			usedList.SetSize(ld->GetNumberTVVerts());//TVMaps.v.Count());
			usedList.ClearAll();

			for (int i = 0; i < ld->GetNumberFaces(); i++)//TVMaps.f.Count(); i++)
			{
				if (!ld->GetFaceDead(i))
				{			
					int degree = ld->GetFaceDegree(i);
					for (int j = 0; j < degree; j++)
					{
						int vertIndex = ld->GetFaceTVVert(i,j);//TVMaps.f[i]->t[j];
						usedList.Set(vertIndex);

						//index into the geometric vertlist
						if ((ld->GetFaceHasVectors(i)/*TVMaps.f[i]->vecs*/) && (j < 4))
						{
							vertIndex = ld->GetFaceTVInterior(i,j);//TVMaps.f[i]->vecs->interiors[j];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);

							vertIndex = ld->GetFaceTVHandle(i,j*2);//TVMaps.f[i]->vecs->handles[j*2];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);
							vertIndex = ld->GetFaceTVHandle(i,j*2+1);//TVMaps.f[i]->vecs->handles[j*2+1];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);
						}

					}
				}
			}

			int vInitalDeadCount = 0;
			int vFinalDeadCount = 0;

			for (int i =0; i < ld->GetNumberTVVerts(); i++)//TVMaps.v.Count(); i++)
			{
				if (ld->GetTVVertDead(i))//TVMaps.v[i].flags & FLAG_DEAD)
					vInitalDeadCount++;
			}

			for (int i =0; i < usedList.GetSize(); i++)
			{
				BOOL isRigPoint = ld->GetTVVertFlag(i) & FLAG_RIGPOINT;
				if (!usedList[i] && (!isRigPoint))
				{
					ld->DeleteTVVert(i,this);
//					TVMaps.v[i].flags |= FLAG_DEAD;
				}
			}

			for (int i =0; i < ld->GetNumberTVVerts(); i++)
			{
				if (ld->GetTVVertDead(i))//TVMaps.v[i].flags & FLAG_DEAD)
					vFinalDeadCount++;
			}


#ifdef DEBUGMODE 

			if (gDebugLevel >= 3)
				ScriptPrint(_T("Cleaning Dead Verts Total Verts %d Initial Dead Verts %d Final Dead Verts %d \n"),vTotalCount,vInitalDeadCount,vFinalDeadCount); 

#endif
		}
	}
IGeometryChecker::ReturnVal OverlappedUVWFacesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val)
{
	val.mIndex.ZeroCount();
	if(IsSupported(nodeToCheck))
	{
		UVWChannel uvmesh;
		ObjectState os  = nodeToCheck->EvalWorldState(t);
		Object *obj = os.obj;
		if(os.obj->IsSubClassOf(triObjectClassID))
		{
			TriObject *tri = dynamic_cast<TriObject *>(os.obj);
			if(tri)
			{
				BitArray arrayOfFaces;
				arrayOfFaces.SetSize(tri->mesh.numFaces);
				arrayOfFaces.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels = tri->mesh.getNumMaps();
				for(int i=0;i<numChannels;++i)
				{
					if(tri->mesh.mapSupport(i))
					{
						uvmesh.DeleteData();
						uvmesh.SetWithMesh(&tri->mesh,i);
						if(uvmesh.GetNumOfFaces()>1)
						{
							//okay now run it with that uvmesh
							returnval = GeometryCheckWithUVMesh(uvmesh,t, nodeToCheck,arrayOfFaces);
							if(returnval ==IGeometryChecker::eFail)
								return returnval;
						}
					}
				}
				if(arrayOfFaces.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfFaces.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfFaces[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
		else if(os.obj->IsSubClassOf(polyObjectClassID))
		{
			PolyObject *poly = dynamic_cast<PolyObject *>(os.obj);
			if(poly)
			{
				BitArray arrayOfFaces;
				arrayOfFaces.SetSize(poly->GetMesh().numf);
				arrayOfFaces.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels= poly->GetMesh().MNum();//do this!
				for(int i=0;i<numChannels;++i)
				{
					if(poly->GetMesh().M(i))
					{
						uvmesh.DeleteData();
						uvmesh.SetWithMesh(&poly->GetMesh(),i);
						if(uvmesh.GetNumOfFaces()>1)
						{
							//okay now run it with that uvmesh
							returnval = GeometryCheckWithUVMesh(uvmesh,t, nodeToCheck,arrayOfFaces);
							if(returnval ==IGeometryChecker::eFail)
								return returnval;
						}
					}
				}
				if(arrayOfFaces.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfFaces.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfFaces[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
		
	}
	return IGeometryChecker::eFail;
}
void MeshTopoData::BuildInitialMapping(PatchMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
			if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
			{
				if (TVMaps.f[i]->vecs)
				{
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]];
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]];
					if (TVMaps.f[i]->flags & FLAG_INTERIOR)
					{
						bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]];
					}
				}
			}

		}

	}
	Tab<int> indexList;

	int vct = msh->numVecs+msh->numVerts;
	indexList.SetCount(vct);
	BitArray usedIndex;
	usedIndex.SetSize(vct);
	usedIndex.ClearAll();

	for (int i = 0; i < vct; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			for (int j = 0; j < pcount; j++)
			{
				//		usedIndex.Set(TVMaps.f[i].t[j]);
				usedIndex.Set(msh->patches[i].v[j]);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							usedIndex.Set(msh->patches[i].interior[j]+msh->numVerts);

						}
					}	
				}

			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->patches[i].v[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f);

				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						//					usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						//					usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						int index;
						int a = msh->patches[i].vec[j*2]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2] = index;
						Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].x/bbox.Width().x + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].y/bbox.Width().y + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].z/bbox.Width().z + 0.5f);
									
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);

						a = msh->patches[i].vec[j*2+1]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2+1] = index;
						uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].x/bbox.Width().x + 0.5f;
						uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].y/bbox.Width().y + 0.5f;
						uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].z/bbox.Width().z + 0.5f;
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);


						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							int index;
							int a = msh->patches[i].interior[j]+msh->numVerts;
							index = indexList[a];
							TVMaps.f[i]->vecs->interiors[j] = index;
							uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].x/bbox.Width().x + 0.5f;
							uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].y/bbox.Width().y + 0.5f;
							uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].z/bbox.Width().z + 0.5f;
							TVMaps.v[index].SetP(uv);  									
							TVMaps.v[index].SetInfluence(0.f);
							TVMaps.v[index].SetFlag(0);
							TVMaps.v[index].SetControlID(-1);

						}
					}	
				}
			}
		}

	}


}
Exemple #30
0
void UnwrapMod::AlignCluster(int baseCluster, int moveCluster, int innerFaceIndex, int outerFaceIndex,int edgeIndex)
	{
//get edges that are coincedent
	int vInner[2];
	int vOuter[2];

	int vInnerVec[2];
	int vOuterVec[2];


	int ct = 0;
	int vct = 0;
	for (int i = 0; i < TVMaps.f[innerFaceIndex]->count; i++)
		{
		int innerIndex = TVMaps.f[innerFaceIndex]->v[i];
		for (int j = 0; j < TVMaps.f[outerFaceIndex]->count; j++)
			{
			int outerIndex = TVMaps.f[outerFaceIndex]->v[j];
			if (innerIndex == outerIndex)
				{
				vInner[ct] = TVMaps.f[innerFaceIndex]->t[i];


				vOuter[ct] = TVMaps.f[outerFaceIndex]->t[j];
				ct++;
				}

			}

		}

	vInnerVec[0] = -1;
	vInnerVec[1] = -1;
	vOuterVec[0] = -1;
	vOuterVec[1] = -1;
	ct = 0;

	if ( (TVMaps.f[innerFaceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[innerFaceIndex]->vecs) &&
		 (TVMaps.f[outerFaceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[outerFaceIndex]->vecs) 
		)
		{
		for (i = 0; i < TVMaps.f[innerFaceIndex]->count*2; i++)
			{
			int innerIndex = TVMaps.f[innerFaceIndex]->vecs->vhandles[i];
			for (int j = 0; j < TVMaps.f[outerFaceIndex]->count*2; j++)
				{
				int outerIndex = TVMaps.f[outerFaceIndex]->vecs->vhandles[j];
				if (innerIndex == outerIndex)
					{
					int vec = TVMaps.f[innerFaceIndex]->vecs->handles[i];
					vInnerVec[ct] = vec;


					vec = TVMaps.f[outerFaceIndex]->vecs->handles[j];
					vOuterVec[ct] = vec;
					ct++;
					}

				}

			}
		}



//get  align vector
	Point3 pInner[2];
	Point3 pOuter[2];

	pInner[0] = TVMaps.v[vInner[0]].p;
	pInner[1] = TVMaps.v[vInner[1]].p;

	pOuter[0] = TVMaps.v[vOuter[0]].p;
	pOuter[1] = TVMaps.v[vOuter[1]].p;

	Point3 offset = pInner[0] - pOuter[0];

	Point3 vecA, vecB;
	vecA = Normalize(pInner[1] - pInner[0]);
	vecB = Normalize(pOuter[1] - pOuter[0]);
	float dot = DotProd(vecA,vecB);

	float angle = 0.0f;
	if (dot == -1.0f)
		angle = PI;
	else if (dot == 1.0f)
		angle = 0.f;
	else angle = acos(dot);

	if ((_isnan(angle)) || (!_finite(angle)))
		angle = 0.0f;
//		DebugPrint("Stop\n");

//	angle = acos(dot);
	
//DebugPrint("angle %f dot %f \n",angle, dot);
/*
DebugPrint("   VecA %f %f %f \n",vecA.x,vecA.y,vecA.z);
DebugPrint("   VecB %f %f %f \n",vecB.x,vecB.y,vecB.z);
*/

 
	Matrix3 tempMat(1);	
	tempMat.RotateZ(angle); 
	Point3 vecC = VectorTransform(tempMat,vecB);




	float negAngle = -angle;
	Matrix3 tempMat2(1);	
	tempMat2.RotateZ(negAngle); 
	Point3 vecD = VectorTransform(tempMat2,vecB);

	float la,lb;
	la = Length(vecA-vecC);
	lb = Length(vecA-vecD);
	if (la > lb)
		angle = negAngle;
	
	clusterList[moveCluster]->newX = offset.x;
	clusterList[moveCluster]->newY = offset.y;
//build vert list
//move those verts
	BitArray processVertList;
	processVertList.SetSize(TVMaps.v.Count());
	processVertList.ClearAll();
	for (i =0; i < clusterList[moveCluster]->faces.Count(); i++)
		{
		int faceIndex = clusterList[moveCluster]->faces[i];
		for (int j =0; j < TVMaps.f[faceIndex]->count; j++)
			{
			int vertexIndex = TVMaps.f[faceIndex]->t[j];
			processVertList.Set(vertexIndex);


			if ( (objType == IS_PATCH) && (TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs))
				{
				int vertIndex;
					
				if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR)
					{
					vertIndex = TVMaps.f[faceIndex]->vecs->interiors[j];
					if ((vertIndex >=0) && (vertIndex < processVertList.GetSize()))
						processVertList.Set(vertIndex);
					}

				vertIndex = TVMaps.f[faceIndex]->vecs->handles[j*2];
				if ((vertIndex >=0) && (vertIndex < processVertList.GetSize()))
					processVertList.Set(vertIndex);
				vertIndex = TVMaps.f[faceIndex]->vecs->handles[j*2+1];
				if ((vertIndex >=0) && (vertIndex < processVertList.GetSize()))
					processVertList.Set(vertIndex);
	
				}


			}
		}
	for (i = 0; i < processVertList.GetSize(); i++)
		{
		if (processVertList[i])
			{
//DebugPrint("%d ",i);
			Point3 p = TVMaps.v[i].p;
//move to origin

			p -= pOuter[0];

//rotate
			Matrix3 mat(1);	

			mat.RotateZ(angle); 

		 	p = p * mat;
//move to anchor point			
			p += pInner[0];

			TVMaps.v[i].p = p;
			if (TVMaps.cont[i]) TVMaps.cont[i]->SetValue(0,&TVMaps.v[i].p);

			}
		}

	if ((vInnerVec[0] != -1) &&	(vInnerVec[1] != -1) && (vOuterVec[0] != -1) && (vOuterVec[1] != -1))
		{
		TVMaps.v[vOuterVec[0]].p = TVMaps.v[vInnerVec[0]].p;
		if (TVMaps.cont[vOuterVec[0]]) TVMaps.cont[vOuterVec[0]]->SetValue(0,&TVMaps.v[vInnerVec[0]].p);

		TVMaps.v[vOuterVec[1]].p = TVMaps.v[vInnerVec[1]].p;
		if (TVMaps.cont[vOuterVec[1]]) TVMaps.cont[vOuterVec[1]]->SetValue(0,&TVMaps.v[vInnerVec[1]].p);

		}



	}