Ejemplo n.º 1
0
void AFRMod::ModifyObject (TimeValue t, ModContext &mc, ObjectState *os, INode *node) {
	Interval iv = FOREVER;
	float f, p, b;
	int backface;
	Point3 pt1, pt2;
	pblock->GetValue(PB_FALLOFF,t,f,iv);
	pblock->GetValue(PB_PINCH,t,p,iv);
	pblock->GetValue(PB_BUBBLE,t,b,iv);
	pblock->GetValue(PB_BACKFACE,t,backface,iv);
	p1->GetValue(t,&pt1,iv,CTRL_ABSOLUTE);
	p2->GetValue(t,&pt2,iv,CTRL_ABSOLUTE);
	if (f==0.0) {
		os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
		return;
	}
	Tab<Point3> normals;
	if (backface) {
		// Need to get vertex normals.
		if (os->obj->IsSubClassOf(triObjectClassID)) {
			TriObject *tobj = (TriObject*)os->obj;
			AverageVertexNormals (tobj->GetMesh(), normals);
		} else if (os->obj->IsSubClassOf (polyObjectClassID)) {
			PolyObject *pobj = (PolyObject *) os->obj;
			MNMesh &mesh = pobj->GetMesh();
			normals.SetCount (mesh.numv);
			Point3 *vn = normals.Addr(0);
			for (int i=0; i<mesh.numv; i++) {
				if (mesh.v[i].GetFlag (MN_DEAD)) vn[i]=Point3(0,0,0);
				else vn[i] = mesh.GetVertexNormal (i);
			}
#ifndef NO_PATCHES
		} else if (os->obj->IsSubClassOf (patchObjectClassID)) {
			PatchObject *pobj = (PatchObject *) os->obj;
			normals.SetCount (pobj->NumPoints ());
			Point3 *vn = normals.Addr(0);
			for (int i=0; i<pobj->NumPoints(); i++) vn[i] = pobj->VertexNormal (i);
#endif
		}
	}
	if (normals.Count()) {
		AFRDeformer deformer(mc,f,p,b,pt1,pt2,&normals);
		os->obj->Deform(&deformer, TRUE);
	} else {
		AFRDeformer deformer(mc,f,p,b,pt1,pt2);
		os->obj->Deform(&deformer, TRUE);
	}	
	os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
	}
Ejemplo n.º 2
0
void PatchDeformPW::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *incnode) 
{
	Interval iv = FOREVER;

	//TODO: Add the code for actually modifying the object
	//check is local data if not create it
	if (mc.localData == NULL)
		{
		LocalPatchData *localData = new LocalPatchData();
		mc.localData = localData;
		}

	LocalPatchData *localData = (LocalPatchData *)mc.localData;

	if (localData == NULL ) return;

	if (localData->selfNode == NULL)
		{
		localData->selfNode = GetNodeFromModContext(localData);
		}


	//check if patch count has changed if so update our uv space
	//if rebuild then 

	INode *node = NULL;
	pblock->GetValue(pb_patch,t,node,iv);


	if (node == NULL)
		{	
		os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
		return;
		}

	ObjectState patchos = node->EvalWorldState(t);
	if ((patchos.obj) && (localData->selfNode))
		{
		iv &= patchos.obj->ObjectValidity(t);

		Matrix3 patchTM = node->GetObjTMBeforeWSM(t, &iv);
		Matrix3 baseTM = localData->selfNode->GetObjTMBeforeWSM(t, &iv);

		PatchObject *patchObj = (PatchObject *) patchos.obj;
		PatchMesh *patch = &patchObj->patch;
		BOOL patchValid = TRUE;
		for (int i =0; i < patch->numPatches; i++)
			{
			if (patch->patches[i].type != PATCH_QUAD)
				{
				patchValid = FALSE;
				}
			}

		if ((!patchValid) && (ip))
			{
			TSTR name;
			name.printf(GetString(IDS_ERROR_TRIPATCH));
			SetWindowText(GetDlgItem(hWnd,IDC_STATUS),name);
			}

		if ((patch->numPatches > 0) && patchValid)
			{
			
			if ( (patch->numPatches != localData->numPatches) ||  (localData->resample))
				{
//rebuild the param data
				BuildParamData(os->obj,localData,patch,patchTM,baseTM);
				
				}
			localData->resample= FALSE;
//setup deformer
			PatchDeformer deformer(localData,patch,baseTM,patchTM);
			os->obj->Deform(&deformer, TRUE);

			}

		}

	os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);
}
Ejemplo n.º 3
0
void MirrorMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
	{	
	Matrix3 itm = CompMatrix(t,NULL,&mc);
	Matrix3 tm  = Inverse(itm);
	Interval iv = FOREVER;
	int axis, copy;
	float offset;
	pblock->GetValue(PB_AXIS,t,axis,iv);
	pblock->GetValue(PB_COPY,t,copy,iv);
	pblock->GetValue(PB_OFFSET,t,offset,iv);
	DWORD oldLevel;
	BOOL convertedShape = FALSE;
	BitArray oldFaceSelections;

	// support for TriObjects
	if (os->obj->IsSubClassOf(triObjectClassID)) {
		TriObject *tobj = (TriObject*)os->obj;
		Mesh &mesh = tobj->GetMesh();		
		switch (mesh.selLevel) {
			case MESH_OBJECT: mesh.faceSel.SetAll(); break;			
			case MESH_VERTEX: {
				for (int i=0; i<mesh.getNumFaces(); i++) {
					for (int j=0; j<3; j++) {
						if (mesh.vertSel[mesh.faces[i].v[j]]) {
							mesh.faceSel.Set(i);
							}
						}
					}
				break;
				}
			
			case MESH_EDGE:	{
				for (int i=0; i<mesh.getNumFaces(); i++) {
					for (int j=0; j<3; j++) {
						if (mesh.edgeSel[i*3+j]) {
							mesh.faceSel.Set(i);
							}
						}
					}
				break;
				}		
			}		
		oldLevel = mesh.selLevel;
		mesh.selLevel = MESH_FACE;
		if (copy) {
			mesh.CloneFaces(mesh.faceSel);
			mesh.ClearVSelectionWeights ();
		}
		if (axis<3) {
			for (int i=0; i<mesh.getNumFaces(); i++) {
				if (mesh.faceSel[i]) mesh.FlipNormal(i);
			}
		}
	}

#ifndef NO_PATCHES
	// support for PatchObjects
	if (os->obj->IsSubClassOf(patchObjectClassID)) {
		PatchObject *pobj = (PatchObject*)os->obj;
		PatchMesh &pmesh = pobj->GetPatchMesh(t);
		switch (pmesh.selLevel) {
			case PATCH_OBJECT: pmesh.patchSel.SetAll(); break;			
			case PATCH_VERTEX: {
				for (int i=0; i<pmesh.getNumPatches(); i++) {
					Patch &p = pmesh.patches[i];
					for (int j=0; j<p.type; j++) {
						if (pmesh.vertSel[p.v[j]]) {
							pmesh.patchSel.Set(i);
							break;
							}
						}
					}
				break;
				}
			
			case PATCH_EDGE:	{
				for (int i=0; i<pmesh.getNumPatches(); i++) {
					Patch &p = pmesh.patches[i];
					for (int j=0; j<p.type; j++) {
						if (pmesh.edgeSel[p.edge[j]]) {
							pmesh.patchSel.Set(i);
							break;
							}
						}
					}
				break;
				}		
			}		
		oldLevel = pmesh.selLevel;
		pmesh.selLevel = PATCH_PATCH;
		if (copy)
			pmesh.ClonePatchParts();	// Copy the selected patches
		if (axis<3)
			pmesh.FlipPatchNormal(-1);	// Flip selected normals
	}
#endif // NO_PATCHES

	// support for PolyObjects
	else if (os->obj->IsSubClassOf(polyObjectClassID)) {
		PolyObject * pPolyOb = (PolyObject*)os->obj;
		MNMesh &mesh = pPolyOb->GetMesh();

		// Luna task 747
		// We don't support specified normals here because it would take special code
		mesh.ClearSpecifiedNormals ();

		BitArray faceSelections;
		mesh.getFaceSel (faceSelections);
		switch (mesh.selLevel) {
			case MNM_SL_OBJECT: faceSelections.SetAll(); break;			
			case MNM_SL_VERTEX: {
				faceSelections.ClearAll ();
				for (int i=0; i<mesh.FNum(); i++) {
					for (int j=0; j<mesh.F(i)->deg; j++) {
						int vertIndex = mesh.F(i)->vtx[j];
						if (mesh.V(vertIndex)->GetFlag(MN_SEL)) {
							faceSelections.Set(i);
							break;
						}
					}
				}
				break;
			}
			
			case MNM_SL_EDGE:	{
				faceSelections.ClearAll ();
				for (int i=0; i<mesh.FNum(); i++) {
					for (int j=0; j<mesh.F(i)->deg; j++) {
						int edgeIndex = mesh.F(i)->edg[j];
						if (mesh.E(edgeIndex)->GetFlag(MN_SEL)) {
							faceSelections.Set(i);
							break;
						}
					}
				}
				break;
			}
		}

		// preserve the existing selection settings
		oldLevel = mesh.selLevel;
		mesh.getFaceSel (oldFaceSelections);

		// set the face selections
		mesh.ClearFFlags (MN_SEL);
		mesh.FaceSelect(faceSelections);
		mesh.selLevel = MNM_SL_FACE;

		// copy the selected faces and flip Normal direction as needed
		if (copy) {
			mesh.CloneFaces();
			mesh.freeVSelectionWeights ();
		}

		// Now, note that by PolyMesh rules, we can only flip entire selected elements.
		// So we broaden our selection to include entire elements that are only partially selected:
		for (int i=0; i<mesh.numf; i++) {
			if (mesh.f[i].GetFlag (MN_DEAD)) continue;
			if (!mesh.f[i].GetFlag (MN_SEL)) continue;
			mesh.PaintFaceFlag (i, MN_SEL);
		}

		if (axis<3) {
			for (i=0; i<mesh.FNum(); i++) {
				if (mesh.F(i)->GetFlag(MN_SEL)) mesh.FlipNormal(i);
			}
			if (mesh.GetFlag (MN_MESH_FILLED_IN)) {
				// We also need to flip edge normals:
				for (i=0; i<mesh.ENum(); i++) {
					if (mesh.f[mesh.e[i].f1].GetFlag (MN_SEL)) {
						int hold = mesh.e[i].v1;
						mesh.e[i].v1 = mesh.e[i].v2;
						mesh.e[i].v2 = hold;
					}
				}
			}
		}
	}

	// support for shape objects
	else
	if (os->obj->IsSubClassOf(splineShapeClassID)) {
		SplineShape *ss = (SplineShape*)os->obj;
		BezierShape &shape = ss->shape;		
		oldLevel = shape.selLevel;
		switch (shape.selLevel) {
			case SHAPE_OBJECT:			
			case SHAPE_VERTEX:
				shape.selLevel = SHAPE_SPLINE;
				shape.polySel.SetAll();
				break;
				 
			case SHAPE_SPLINE:
			case SHAPE_SEGMENT:
				break;
			}		
		if (copy)
			shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE);
		}
	else
	if(os->obj->SuperClassID() == SHAPE_CLASS_ID) {
		ShapeObject *so = (ShapeObject *)os->obj;
		if(so->CanMakeBezier()) {
			SplineShape *ss = new SplineShape();
			so->MakeBezier(t, ss->shape);
			ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t));
			os->obj = ss;
			os->obj->UnlockObject();
			convertedShape = TRUE;
			BezierShape &shape = ss->shape;		
			oldLevel = shape.selLevel;
			switch (shape.selLevel) {
				case SHAPE_OBJECT:			
				case SHAPE_VERTEX:
					shape.selLevel = SHAPE_SPLINE;
					shape.polySel.SetAll();
					break;
					 
				case SHAPE_SPLINE:
				case SHAPE_SEGMENT:
					break;
				}		
			if (copy)
				shape.CloneSelectedParts((axis < 3 && splineMethod == SPLINE_REVERSE) ? TRUE : FALSE);
			}
		}

	MirrorDeformer deformer(axis,offset,tm,itm);


	os->obj->Deform(&deformer, TRUE);	

//	if (axis < 3 && splineMethod == SPLINE_REVERSE)
		{
		if (os->obj->IsSubClassOf(splineShapeClassID)) {
			SplineShape *ss = (SplineShape*)os->obj;
			BezierShape &shape = ss->shape;		
			for (int i = 0; i < shape.bindList.Count(); i++)
				{
				int index = 0;
				int spindex = shape.bindList[i].pointSplineIndex;
//			Point3 p=shape.splines[spindex]->GetKnot(index).Knot();
				if (shape.bindList[i].isEnd)
					index = shape.splines[spindex]->KnotCount()-1;
				shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index);
				shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index);
				}
			shape.UpdateBindList(TRUE);
	
			}
		else
		if(os->obj->SuperClassID() == SHAPE_CLASS_ID) {
			ShapeObject *so = (ShapeObject *)os->obj;
			if(so->CanMakeBezier()) {
				SplineShape *ss = new SplineShape();
				so->MakeBezier(t, ss->shape);
				ss->SetChannelValidity(GEOM_CHAN_NUM, GetValidity(t) & so->ObjectValidity(t));
				os->obj = ss;
				os->obj->UnlockObject();
				convertedShape = TRUE;
				BezierShape &shape = ss->shape;		
				for (int i = 0; i < shape.bindList.Count(); i++)
					{
					int index = 0;
					int spindex = shape.bindList[i].pointSplineIndex;
//				Point3 p;
					if (shape.bindList[i].isEnd)
						index = shape.splines[spindex]->KnotCount()-1;
					shape.bindList[i].bindPoint = shape.splines[spindex]->GetKnotPoint(index);
					shape.bindList[i].segPoint = shape.splines[spindex]->GetKnotPoint(index);
					}
				shape.UpdateBindList(TRUE);

				}

			}
		}

	os->obj->UpdateValidity(GEOM_CHAN_NUM,GetValidity(t));	
	
	// restore the original selections
	if (os->obj->IsSubClassOf(triObjectClassID)) {
		TriObject *tobj = (TriObject*)os->obj;
		tobj->GetMesh().selLevel = oldLevel;
		}
#ifndef NO_PATCHES
	else if (os->obj->IsSubClassOf(patchObjectClassID)) {
		PatchObject *pobj = (PatchObject*)os->obj;
		pobj->GetPatchMesh(t).selLevel = oldLevel;
		}
#endif // NO_PATCHES
	else if (os->obj->IsSubClassOf(polyObjectClassID)) {
		PolyObject *pPolyOb = (PolyObject*)os->obj;
		pPolyOb->GetMesh().selLevel = oldLevel;
		pPolyOb->GetMesh().dispFlags = 0;
		switch (oldLevel) {
		case MNM_SL_VERTEX:
			pPolyOb->GetMesh().dispFlags = MNDISP_SELVERTS | MNDISP_VERTTICKS;
			break;
		case MNM_SL_EDGE:
			pPolyOb->GetMesh().dispFlags = MNDISP_SELEDGES;
			break;
		case MNM_SL_FACE:
			pPolyOb->GetMesh().dispFlags = MNDISP_SELFACES;
			break;
		}
		pPolyOb->GetMesh().FaceSelect(oldFaceSelections);
		}
	else
	if(os->obj->IsSubClassOf(splineShapeClassID) || convertedShape) {
		SplineShape *ss = (SplineShape*)os->obj;
		ss->shape.selLevel = oldLevel;
		}
	}