Пример #1
0
void EditPatchMod::ChangeSelVerts(int type) 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	BOOL holdNeeded = FALSE;
	BOOL hadSelected = FALSE;
	
	if (!ip)
		return;
	
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	theHold.Begin();
	for (int i = 0; i < mcList.Count(); i++)
	{
		BOOL altered = FALSE;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);
		
		// If any bits are set in the selection set, let's DO IT!!
		if (patch->vertSel.NumberSet())
		{
			altered = holdNeeded = TRUE;
			if (theHold.Holding())
				theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "ChangeSelVerts"));
			// Call the vertex type change function
			patch->ChangeVertType(-1, type);
			patchData->UpdateChanges(patch, rpatch, FALSE);
			patchData->TempData(this)->Invalidate(PART_TOPO);
		}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	if (holdNeeded)
		theHold.Accept(GetString(IDS_TH_VERTCHANGE));
	else 
	{
		ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), PROMPT_TIME);
		theHold.End();
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
}
Пример #2
0
void EditPatchMod::RemoveSubSelSet(TSTR &setName)
{
	MaybeFixupNamedSels();
	
	ModContextList mcList;
	INodeTab nodes;
	
	if (!ip)
		return;	
	
	ip->GetModContexts(mcList, nodes);
	
	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;		
		patchData->BeginEdit(ip->GetTime());
		GenericNamedSelSetList &sel = patchData->GetSelSet(this);
		sel.RemoveSet(setName);
	}
	// Remove the modifier's entry
	RemoveSet(setName, selLevel);
	ip->ClearCurNamedSelSet();
	SetupNamedSelDropDown();
	nodes.DisposeTemporary();
}
Пример #3
0
void EditPatchMod::ActivateSubSelSet(TSTR &setName)
{
	MaybeFixupNamedSels();
	ModContextList mcList;
	INodeTab nodes;
	int index = FindSet(setName, selLevel);
	if (index < 0 || !ip)
		return;	
	
	ip->GetModContexts(mcList, nodes);
	
	theHold.Begin();
	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;		
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
		if (!patch)
			continue;
		patchData->BeginEdit(ip->GetTime());
		// If that set exists in this context, deal with it
		GenericNamedSelSetList &sel = patchData->GetSelSet(this);
		BitArray *set = sel.GetSet(setName);
		if (set)
		{
			if (theHold.Holding())
				theHold.Put(new PatchSelRestore(patchData, this, patch));
			BitArray *psel = GetLevelSelectionSet(patch, rpatch);	// Get the appropriate selection set
			AssignSetMatchSize(*psel, *set);				
			PatchSelChanged();
		}
		
		patchData->UpdateChanges(patch, rpatch, FALSE);
		if (patchData->tempData)
			patchData->TempData(this)->Invalidate(PART_SELECT);
	}
	
	theHold.Accept(GetString(IDS_DS_SELECT));
	nodes.DisposeTemporary();	
	NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime());
}
Пример #4
0
void EditPatchMod::SelectSubPatch(int index)
{
	if (!ip)
		return; 
	TimeValue t = ip->GetTime();

	ip->ClearCurNamedSelSet();

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

	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
	
		if (!patchData)
			return;
		
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			return;
		
		patchData->BeginEdit(t);
		if (theHold.Holding()) 
			theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "SelectSubComponent"));

		patch->patchSel.Set(index);

		patchData->UpdateChanges(patch, rpatch, FALSE);
		if (patchData->tempData)
		{
			patchData->tempData->Invalidate(PART_SELECT);
		}
	}
	PatchSelChanged();
		
	UpdateSelectDisplay();
	NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
Пример #5
0
void EditPatchMod::DoVertReset ()
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	int holdNeeded = 0;
	BOOL hadSel = FALSE;

	if (!ip)
		return;

	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);

	theHold.Begin();
	RecordTopologyTags();
	for (int i = 0; i < mcList.Count(); i++)
	{
		BOOL altered = FALSE;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;

		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		patchData->RecordTopologyTags(patch);
		
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);

		// If any bits are set in the selection set, let's DO IT!!
		if (patch->vertSel.NumberSet() > 0)
		{
			hadSel = TRUE;
			if (theHold.Holding())
				theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoVertReset"));
			// Call the patch weld function
			ResetVert (patch);
			patchData->UpdateChanges(patch, rpatch);
			patchData->TempData(this)->Invalidate(PART_GEOM);
			/*if (patch->Weld(weldThreshold))
			{
				rpatch->Weld (patch);
				altered = holdNeeded = TRUE;
				patchData->UpdateChanges(patch, rpatch);
				patchData->TempData(this)->Invalidate(PART_TOPO);
			}*/
		}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	ResolveTopoChanges();
	theHold.Accept("Reset Vertex");
	/*if (holdNeeded)
	{
		ResolveTopoChanges();
		theHold.Accept(GetString(IDS_TH_VERTWELD));
	}
	else 
	{
		if (!hadSel)
			ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), PROMPT_TIME);
		else
			ip->DisplayTempPrompt(GetString(IDS_TH_NOWELDPERFORMED), PROMPT_TIME);
		theHold.End();
	}*/

	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
}
Пример #6
0
void EditPatchMod::InvertSelection(int selLevel) 
{
	// Don't do anything if at vertex level with verts turned off
	if (selLevel == EP_VERTEX && !filterVerts)
		return;
	if (selLevel == EP_OBJECT)
		return;
	
	ModContextList mcList;
	INodeTab nodes;
	
	if (!ip)
		return;	
	
	ip->GetModContexts(mcList, nodes);
	ip->ClearCurNamedSelSet();
	
	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;		
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
		if (!patch)
			continue;
		
		patchData->BeginEdit(ip->GetTime());
		if (theHold.Holding())
			theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "InvertSelection"));
		
		switch (selLevel)
		{
		case EP_VERTEX: 
			{
				patch->vertSel = ~patch->vertSel;
				break;
			}
		case EP_EDGE: 
			{
				patch->edgeSel = ~patch->edgeSel;
				break;
			}
		case EP_PATCH: 
			{
				patch->patchSel = ~patch->patchSel;
				break;
			}
		case EP_TILE: 
			{
				rpatch->tileSel = ~rpatch->tileSel;
				break;
			}
		}
		UnselectHiddenPatches(selLevel, patch);
		patchData->UpdateChanges(patch, rpatch, FALSE);
		if (patchData->tempData)
		{
			patchData->TempData(this)->Invalidate(PART_SELECT);
		}
		PatchSelChanged();
	}
	nodes.DisposeTemporary();
	NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
Пример #7
0
	void EditPatchMod::SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert)
{
	// Don't do anything if at vertex level with verts turned off
	if (selLevel == EP_VERTEX && !filterVerts)
		return;

	if (!ip)
		return; 
	TimeValue t = ip->GetTime();

	ip->ClearCurNamedSelSet();

	// Keep processing hit records as long as we have them!
	while (hitRec) 
	{	
		EditPatchData *patchData =(EditPatchData*)hitRec->modContext->localData;
		
		if (!patchData)
			return;
		
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			return;
		
		patchData->BeginEdit(t);
		if (theHold.Holding()) 
			theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "SelectSubComponent"));
		
		switch (selLevel)
		{
		case EP_VERTEX: 
			{
				if (all)
				{				
					if (invert)
					{
						while (hitRec) 
						{
							// If the object changes, we're done!
							if (patchData !=(EditPatchData*)hitRec->modContext->localData)
								goto vert_done;
							int index =((PatchHitData *)(hitRec->hitData))->index;
							if (((PatchHitData *)(hitRec->hitData))->type == PATCH_HIT_VERTEX)
							{
								if (patch->vertSel[index])
									patch->vertSel.Clear(index);
								else
									patch->vertSel.Set(index);
							}
							hitRec = hitRec->Next();
						}
					}
					else
						if (selected)
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto vert_done;
								PatchHitData *hit =(PatchHitData *)(hitRec->hitData);
								if (hit->type == PATCH_HIT_VERTEX)
									patch->vertSel.Set(hit->index);
								hitRec = hitRec->Next();
							}
						}
						else 
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto vert_done;
								PatchHitData *hit =(PatchHitData *)(hitRec->hitData);
								if (hit->type == PATCH_HIT_VERTEX)
									patch->vertSel.Clear(hit->index);
								hitRec = hitRec->Next();
							}
						}
				}
				else 
				{
					int index =((PatchHitData *)(hitRec->hitData))->index;
					if (((PatchHitData *)(hitRec->hitData))->type == PATCH_HIT_VERTEX)
					{
						if (invert)
						{
							if (patch->vertSel[index])
								patch->vertSel.Clear(index);
							else
								patch->vertSel.Set(index);
						}
						else
							if (selected)
 								patch->vertSel.Set(index);
							else
								patch->vertSel.Clear(index);
					}
					hitRec = NULL;	// Reset it so we can exit	
				}
vert_done:
				break;
			}
		case EP_EDGE: 
			{
				if (all)
				{				
					if (invert)
					{
						while (hitRec) 
						{
							// If the object changes, we're done!
							if (patchData !=(EditPatchData*)hitRec->modContext->localData)
								goto edge_done;
							int index =((PatchHitData *)(hitRec->hitData))->index;
							if (patch->edgeSel[index])
								patch->edgeSel.Clear(index);
							else
								patch->edgeSel.Set(index);
							hitRec = hitRec->Next();
						}
					}
					else
						if (selected)
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto edge_done;
								patch->edgeSel.Set(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
						else 
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto edge_done;
								patch->edgeSel.Clear(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
				}
				else 
				{
					int index =((PatchHitData *)(hitRec->hitData))->index;
					if (invert)
					{
						if (patch->edgeSel[index])
							patch->edgeSel.Clear(index);
						else
							patch->edgeSel.Set(index);
					}
					else
						if (selected)
						{
							patch->edgeSel.Set(index);
						}
						else 
						{
							patch->edgeSel.Clear(index);
						}
						hitRec = NULL;	// Reset it so we can exit	
				}
edge_done:
				break;
			}
		case EP_PATCH: 
			{
				if (all)
				{				
					if (invert)
					{
						while (hitRec) 
						{
							// If the object changes, we're done!
							if (patchData !=(EditPatchData*)hitRec->modContext->localData)
								goto patch_done;
							int index =((PatchHitData *)(hitRec->hitData))->index;
							if (patch->patchSel[index])
								patch->patchSel.Clear(index);
							else
								patch->patchSel.Set(index);
							hitRec = hitRec->Next();
						}
					}
					else
						if (selected)
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto patch_done;
								patch->patchSel.Set(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
						else 
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto patch_done;
								patch->patchSel.Clear(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
				}
				else 
				{
					int index =((PatchHitData *)(hitRec->hitData))->index;
					if (invert)
					{
						if (patch->patchSel[index])
							patch->patchSel.Clear(index);
						else
							patch->patchSel.Set(index);
					}
					else
						if (selected)
						{
							patch->patchSel.Set(index);
						}
						else 
						{
							patch->patchSel.Clear(index);
						}
						hitRec = NULL;	// Reset it so we can exit	
				}
patch_done:
				break;
			}
		case EP_TILE:
			{
				if (all)
				{
					if (invert)
					{
						while (hitRec)
						{
							// If the object changes, we're done!
							if (patchData !=(EditPatchData*)hitRec->modContext->localData)
								goto tile_done;
							int index =((PatchHitData *)(hitRec->hitData))->index;
							if (rpatch->tileSel[index])
								rpatch->tileSel.Clear(index);
							else
								rpatch->tileSel.Set(index);
							hitRec = hitRec->Next();
						}
					}
					else
						if (selected)
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto tile_done;
								rpatch->tileSel.Set(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
						else 
						{
							while (hitRec) 
							{
								// If the object changes, we're done!
								if (patchData !=(EditPatchData*)hitRec->modContext->localData)
									goto tile_done;
								rpatch->tileSel.Clear(((PatchHitData *)(hitRec->hitData))->index);
								hitRec = hitRec->Next();
							}
						}
				}
				else 
				{
					int index =((PatchHitData *)(hitRec->hitData))->index;
					if (invert)
					{
						if (rpatch->tileSel[index])
							rpatch->tileSel.Clear(index);
						else
							rpatch->tileSel.Set(index);
					}
					else
						if (selected)
						{
							rpatch->tileSel.Set(index);
						}
						else 
						{
							rpatch->tileSel.Clear(index);
						}
						hitRec = NULL;	// Reset it so we can exit	
				}
tile_done:
				break;
			}
		case EP_OBJECT:
		default:
			return;
		}
		patchData->UpdateChanges(patch, rpatch, FALSE);
		if (patchData->tempData)
		{
			patchData->tempData->Invalidate(PART_SELECT);
		}
		PatchSelChanged();
	}
		
	UpdateSelectDisplay();
	NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
Пример #8
0
int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPatch, bool & canUndo)
{
    ModContextList mcList;
    INodeTab nodes;

    if (!ip)
        return 0;

    ip->GetModContexts(mcList, nodes);

    if (mcList.Count() != 1)
    {
        nodes.DisposeTemporary();
        return 0;
    }

    EditPatchData *patchData =(EditPatchData*)mcList[0]->localData;
    if (!patchData)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->BeginEdit(ip->GetTime());

    // If the mesh isn't yet cached, this will cause it to get cached.
    RPatchMesh *rpatch;
    PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
    if (!patch)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->RecordTopologyTags(patch);
    RecordTopologyTags();

    // Transform the shape for attachment:
    // If reorienting, just translate to align pivots
    // Otherwise, transform to match our transform
    Matrix3 attMat(1);
    if (attachReorient)
    {
        Matrix3 thisTM = nodes[0]->GetNodeTM(ip->GetTime());
        Matrix3 thisOTMBWSM = nodes[0]->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 thisPivTM = thisTM * Inverse(thisOTMBWSM);
        Matrix3 otherTM = node->GetNodeTM(ip->GetTime());
        Matrix3 otherOTMBWSM = node->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 otherPivTM = otherTM * Inverse(otherOTMBWSM);
        Point3 otherObjOffset = node->GetObjOffsetPos();
        attMat = Inverse(otherPivTM) * thisPivTM;
    }
    else
    {
        attMat = node->GetObjectTM(ip->GetTime()) *
                 Inverse(nodes[0]->GetObjectTM(ip->GetTime()));
    }

    // RB 3-17-96 : Check for mirroring
    AffineParts parts;
    decomp_affine(attMat, &parts);
    if (parts.f < 0.0f)
    {
        int v[8], ct, ct2, j;
        Point3 p[9];

        for (int i = 0; i < attPatch->numPatches; i++)
        {

            // Re-order rpatch
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                UI_PATCH rpatch=rattPatch->getUIPatch (i);
                int ctU=rpatch.NbTilesU<<1;
                int ctV=rpatch.NbTilesV<<1;
                int nU;
                for (nU=0; nU<ctU; nU++)
                {
                    for (int nV=0; nV<ctV; nV++)
                    {
                        rattPatch->getUIPatch (i).getTileDesc (nU+nV*ctU)=rpatch.getTileDesc (ctU-1-nU+(ctV-1-nV)*ctU);
                    }
                }
                for (nU=0; nU<ctU+1; nU++)
                {
                    for (int nV=0; nV<ctV+1; nV++)
                    {
                        rattPatch->getUIPatch (i).setColor (nU+nV*(ctU+1), rpatch.getColor (ctU-nU+(ctV-nV)*ctU));
                    }
                }
            }

            // Re-order vertices
            ct = attPatch->patches[i].type == PATCH_QUAD ? 4 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].v[j];
            }
            for (j = 0; j < ct; j++)
            {
                attPatch->patches[i].v[j] = v[ct - j - 1];
            }

            // Re-order vecs
            ct  = attPatch->patches[i].type == PATCH_QUAD ? 8 : 6;
            ct2 = attPatch->patches[i].type == PATCH_QUAD ? 5 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].vec[j];
            }
            for (j = 0; j < ct; j++, ct2--)
            {
                if (ct2 < 0)
                    ct2 = ct - 1;
                attPatch->patches[i].vec[j] = v[ct2];
            }

            // Re-order enteriors
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                ct = 4;
                for (j = 0; j < ct; j++)
                {
                    v[j] = attPatch->patches[i].interior[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].interior[j] = v[ct - j - 1];
                }
            }

            // Re-order aux
            if (attPatch->patches[i].type == PATCH_TRI)
            {
                ct = 9;
                for (j = 0; j < ct; j++)
                {
                    p[j] = attPatch->patches[i].aux[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].aux[j] = p[ct - j - 1];
                }
            }

            // Re-order TV faces if present
            for (int chan = 0; chan < patch->getNumMaps(); ++chan)
            {
                if (attPatch->tvPatches[chan])
                {
                    ct = 4;
                    for (j = 0; j < ct; j++)
                    {
                        v[j] = attPatch->tvPatches[chan][i].tv[j];
                    }
                    for (j = 0; j < ct; j++)
                    {
                        attPatch->tvPatches[chan][i].tv[j] = v[ct - j - 1];
                    }
                }
            }
        }
    }

    int i;
    for (i = 0; i < attPatch->numVerts; ++i)
        attPatch->verts[i].p = attPatch->verts[i].p * attMat;
    for (i = 0; i < attPatch->numVecs; ++i)
        attPatch->vecs[i].p = attPatch->vecs[i].p * attMat;
    attPatch->computeInteriors();

    theHold.Begin();

    // Combine the materials of the two nodes.
    int mat2Offset = 0;
    Mtl *m1 = nodes[0]->GetMtl();
    Mtl *m2 = node->GetMtl();
    bool condenseMe = FALSE;
    if (m1 && m2 &&(m1 != m2))
    {
        if (attachMat == ATTACHMAT_IDTOMAT)
        {
            int ct = 1;
            if (m1->IsMultiMtl())
                ct = m1->NumSubMtls();
            for (int i = 0; i < patch->numPatches; ++i)
            {
                int mtid = patch->getPatchMtlIndex(i);
                if (mtid >= ct)
                    patch->setPatchMtlIndex(i, mtid % ct);
            }
            FitPatchIDsToMaterial(*attPatch, m2);
            if (condenseMat)
                condenseMe = TRUE;
        }
        // the theHold calls here were a vain attempt to make this all undoable.
        // This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO.
        theHold.Suspend();
        if (attachMat == ATTACHMAT_MATTOID)
        {
            m1 = FitMaterialToPatchIDs(*patch, m1);
            m2 = FitMaterialToPatchIDs(*attPatch, m2);
        }

        Mtl *multi = CombineMaterials(m1, m2, mat2Offset);
        if (attachMat == ATTACHMAT_NEITHER)
            mat2Offset = 0;
        theHold.Resume();
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = patch->selLevel;
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(multi);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = multi;
        canUndo = FALSE;	// Absolutely cannot undo material combinations.
    }
    if (!m1 && m2)
    {
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = rpatch->GetSelLevel();
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(m2);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = m2;
    }

    // Start a restore object...
    if (theHold.Holding())
        theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoAttach"));

    // Do the attach
    patch->Attach(attPatch, mat2Offset);
    rpatch->Attach(rattPatch, *patch);
    patchData->UpdateChanges(patch, rpatch);
    patchData->TempData(this)->Invalidate(PART_TOPO | PART_GEOM);

    // Get rid of the original node
    ip->DeleteNode(node);

    ResolveTopoChanges();
    theHold.Accept(GetString(IDS_TH_ATTACH));

    if (m1 && condenseMe)
    {
        // Following clears undo stack.
        patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
        m1 = CondenseMatAssignments(*patch, m1);
    }

    nodes.DisposeTemporary();
    ClearPatchDataFlag(mcList, EPD_BEENDONE);
    NotifyDependents(FOREVER, PART_TOPO | PART_GEOM, REFMSG_CHANGE);
    ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
    return 1;
}
Пример #9
0
void EditPatchMod::DoAddHook(PatchMesh *pMesh, int vert0, int vert1, int vert2, int seg, int config)
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	BOOL holdNeeded = FALSE;
	BOOL hadSelected = FALSE;

	if (!ip)
		return;

	ip->GetModContexts(mcList, nodes);


	if (mcList.Count() != 1)
		return;

	ClearPatchDataFlag(mcList, EPD_BEENDONE);

	theHold.Begin();
//	RecordTopologyTags();
	for (int i = 0; i < mcList.Count(); i++)
	{
		BOOL altered = FALSE;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;

		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if ((!patch) ||(patch != pMesh))
			continue;		
//		patchData->RecordTopologyTags(patch);
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);

		// If any bits are set in the selection set, let's DO IT!!
//		if(patch->vertSel.NumberSet()) {

		altered = holdNeeded = TRUE;
		if (theHold.Holding())
			theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
			// Call the vertex type change function
		
		// ** Hulud bug hack for hooking my way  \\\\\\\\\///////////

		//patch->AddHook(vert1, seg);

		// Config 0
		switch (config)
		{
		case 0:
			rpatch->AddHook (vert1, seg, *patch);
			break;
		case 1:
			rpatch->AddHook (vert0, vert1, vert2, seg, *patch);
			break;
		default:
			nlassert (0);
		}

		// ** //////////\\\\\\\\\\

//		patch->UpdateHooks();
//			InvalidateMesh();

		patchData->UpdateChanges(patch, rpatch);
		patchData->TempData(this)->Invalidate(PART_TOPO);
//			}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
		}
	
	if (holdNeeded)
	{
//		ResolveTopoChanges();
		theHold.Accept(GetString(IDS_TH_PATCHCHANGE));
		}
	else 
	{
		ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
		theHold.End();
		}

	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);

/*	// If any bits are set in the selection set, let's DO IT!!
	if (!ip)
	return;
	theHold.Begin();
	POPatchGenRecord *rec = new POPatchGenRecord(this);
	if (theHold.Holding())
		theHold.Put(new PatchObjectRestore(this, rec));
		// Call the patch type change function

	patch.AddHook();
	patch.InvalidateGeomCache();
	InvalidateMesh();
	theHold.Accept(GetResString(IDS_TH_PATCHCHANGE));

	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
*/
	}
Пример #10
0
void EditPatchMod::DoPatchDelete() 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	int holdNeeded = 0;
	
	if (!ip)
		return;
	
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	theHold.Begin();
	RecordTopologyTags();
	for (int i = 0; i < mcList.Count(); i++)
	{
		int altered = 0;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		patchData->RecordTopologyTags(patch);
		
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);

		// If any bits are set in the selection set, let's DO IT!!
		if (patch->patchSel.NumberSet())
		{
			altered = holdNeeded = 1;
			if (theHold.Holding())
				theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoPatchDelete"));
			// Call the patch delete function
			DeleteSelPatches(patch, rpatch);
			patchData->UpdateChanges(patch, rpatch);
			patchData->TempData(this)->Invalidate(PART_TOPO);
		}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	if (holdNeeded)
	{
		ResolveTopoChanges();
		theHold.Accept(GetString(IDS_TH_PATCHDELETE));
	}
	else 
	{
		ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
		theHold.End();
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
}
Пример #11
0
// Edger Delete modifier method
void EditPatchMod::DoEdgeDelete() 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	int holdNeeded = 0;
	
	if (!ip)
		return;
	
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	theHold.Begin();
	RecordTopologyTags();
	for (int i = 0; i < mcList.Count(); i++)
	{
		int altered = 0;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		patchData->RecordTopologyTags(patch);
		
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);
		
		// If any bits are set in the selection set, let's DO IT!!
		if (patch->edgeSel.NumberSet())
		{
			altered = holdNeeded = 1;
			if (theHold.Holding())
				theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoEdgeDelete"));
			int edges = patch->getNumEdges();
			int patches = patch->getNumPatches();
			int verts = patch->getNumVerts();
			
			// Tag the patches that are attached to selected edges
			BitArray delPatches(patches);
			delPatches.ClearAll();
			
			for (int i = 0; i < edges; ++i)
			{
				if (patch->edgeSel[i])
				{
#if (MAX_RELEASE < 4000)
					if (patch->edges[i].patch1 >= 0)
						delPatches.Set(patch->edges[i].patch1);
					if (patch->edges[i].patch2 >= 0)
						delPatches.Set(patch->edges[i].patch2);
#else // (MAX_RELEASE < 4000)
					if (patch->edges[i].patches[0] >= 0)
						delPatches.Set(patch->edges[i].patches[0]);
					if (patch->edges[i].patches[1] >= 0)
						delPatches.Set(patch->edges[i].patches[1]);
#endif // (MAX_RELEASE < 4000)
				}
			}
			
			BitArray delVerts(verts);
			delVerts.ClearAll();
			
			DeletePatchParts(patch, rpatch, delVerts, delPatches);
			patch->computeInteriors();
			
			patchData->UpdateChanges(patch, rpatch);
			patchData->TempData(this)->Invalidate(PART_TOPO);
		}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	if (holdNeeded)
	{
		ResolveTopoChanges();
		theHold.Accept(GetString(IDS_TH_EDGEDELETE));
	}
	else 
	{
		ip->DisplayTempPrompt(GetString(IDS_TH_NOEDGESSEL), PROMPT_TIME);
		theHold.End();
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
}