Exemple #1
0
Object* SimpleObject::ConvertToType(TimeValue t, Class_ID obtype) 
	{
	if (obtype==defObjectClassID||obtype==triObjectClassID||obtype==mapObjectClassID) {
		TriObject *triob;
		UpdateMesh(t);
		triob = CreateNewTriObject();
		triob->GetMesh() = mesh;
		triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));		
		return triob;
		}
#ifndef NO_PATCHES
	if (obtype == patchObjectClassID) {
		UpdateMesh(t);
		PatchObject *patchob = new PatchObject();
		patchob->patch = mesh;		// Handy Mesh->PatchMesh conversion
		patchob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		patchob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));		
		return patchob;
		}
#endif
	if (Object::CanConvertToType (obtype)) {
		UpdateMesh (t);
	return Object::ConvertToType(t,obtype);
	}
	if (CanConvertTriObject(obtype)) {
		UpdateMesh (t);
		TriObject *triob = CreateNewTriObject ();
		triob->GetMesh() = mesh;
		triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));		
		Object *ob = triob->ConvertToType (t, obtype);
		if (ob != triob) triob->DeleteThis ();	// (ob should never = tob.)
		return ob;
	}
	return NULL;
}
Object* bhkProxyObject::ConvertToType(TimeValue t, Class_ID obtype)
{
	if (obtype == triObjectClassID)
	{
		int bvType = 0;
		pblock2->GetValue(PB_BOUND_TYPE, 0, bvType, FOREVER, 0);
		if (bvType != 0) 
		{
			TriObject *ob = CreateNewTriObject();
#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+
			ob->GetMesh().CopyBasics(proxyMesh);
#else
			ob->GetMesh() = proxyMesh;
#endif
			ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
			ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));
			return ob;
		}
	}
	return 0;
}
Exemple #3
0
Object* SimpleObject::ConvertToType(TimeValue t, Class_ID obtype) 
	{
	if (obtype==defObjectClassID||obtype==triObjectClassID||obtype==mapObjectClassID) {
		TriObject *triob;
		UpdateMesh(t);
		triob = CreateNewTriObject();
		triob->GetMesh() = mesh;
		triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));		
		return triob;
		}
	else
	if (obtype == patchObjectClassID) {
		UpdateMesh(t);
		PatchObject *patchob = new PatchObject();
		patchob->patch = mesh;		// Handy Mesh->PatchMesh conversion
		patchob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		patchob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));		
		return patchob;
		}
	return Object::ConvertToType(t,obtype);
	}
Exemple #4
0
void SmoothMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) {
   Interval valid = FOREVER;
   int autoSmooth, bits = 0, prevent = 0;
   float thresh = 0.0f;
   pblock->GetValue(sm_autosmooth, t, autoSmooth, valid);
   if (autoSmooth) {
      pblock->GetValue(sm_threshold, t, thresh, valid);
      pblock->GetValue(sm_prevent_indirect, t, prevent, valid);
   } else {
      pblock->GetValue(sm_smoothbits, t, bits, valid);
   }
   // For version 4 and later, we process patch meshes as they are and pass them on.  Earlier
   // versions converted to TriMeshes (done below).  For adding other new types of objects, add
   // them here!
   bool done = false;
#ifndef NO_PATCHES
   if(version >= MATMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
      PatchObject *patchOb = (PatchObject *)os->obj;
      PatchMesh &pmesh = patchOb->GetPatchMesh(t);
      BOOL useSel = pmesh.selLevel >= PO_PATCH;

      if (autoSmooth) pmesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int i=0; i<pmesh.getNumPatches(); i++) {
            if (!useSel || pmesh.patchSel[i]) pmesh.patches[i].smGroup = (DWORD)bits;
         }
      }
      pmesh.InvalidateGeomCache();  // Do this because there isn't a topo cache in PatchMesh
      patchOb->UpdateValidity(TOPO_CHAN_NUM,valid);
      done = true;
   }
#endif // NO_PATCHES
   if (!done && os->obj->IsSubClassOf (polyObjectClassID)) {
      PolyObject *pPolyOb = (PolyObject *)os->obj;
      MNMesh &mesh = pPolyOb->GetMesh();

      BOOL useSel = (mesh.selLevel == MNM_SL_FACE);
      if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int faceIndex=0; faceIndex<mesh.FNum(); faceIndex++) {
            if (!useSel || mesh.F(faceIndex)->GetFlag(MN_SEL)) {
               mesh.F(faceIndex)->smGroup = (DWORD)bits;
            }
         }
      }

      // Luna task 747
      // We need to rebuild the smoothing-group-based normals in the normalspec, if any:
      if (mesh.GetSpecifiedNormals()) {
         mesh.GetSpecifiedNormals()->SetParent (&mesh);
         mesh.GetSpecifiedNormals()->BuildNormals ();
         mesh.GetSpecifiedNormals()->ComputeNormals ();
      }

      pPolyOb->UpdateValidity(TOPO_CHAN_NUM,valid);
      done = true;
   }

   TriObject *triOb = NULL;
   if (!done) {
      if (os->obj->IsSubClassOf(triObjectClassID)) triOb = (TriObject *)os->obj;
      else {
         // Convert to triobject if we can.
         if(os->obj->CanConvertToType(triObjectClassID)) {
            TriObject  *triOb = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);

            // We'll need to stuff this back into the pipeline:
            os->obj = triOb;

            // Convert validities:
            Interval objValid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
            triOb->SetChannelValidity (TOPO_CHAN_NUM, objValid);
            triOb->SetChannelValidity (GEOM_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, GEOM_CHAN_NUM));
            triOb->SetChannelValidity (TEXMAP_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM));
            triOb->SetChannelValidity (VERT_COLOR_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM));
            triOb->SetChannelValidity (DISP_ATTRIB_CHAN_NUM,
               objValid & os->obj->ChannelValidity (t, DISP_ATTRIB_CHAN_NUM));
         }
      }
   }

   if (triOb) {   // one way or another, there's a triobject to smooth.
      Mesh & mesh = triOb->GetMesh();
      BOOL useSel = mesh.selLevel == MESH_FACE;
      if (autoSmooth) mesh.AutoSmooth (thresh, useSel, prevent);
      else {
         for (int i=0; i<mesh.getNumFaces(); i++) {
            if (!useSel || mesh.faceSel[i]) mesh.faces[i].smGroup = (DWORD)bits;
         }
      }
      triOb->GetMesh().InvalidateTopologyCache();
      triOb->UpdateValidity(TOPO_CHAN_NUM,valid);     
   }
}
Exemple #5
0
void RelaxMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) {	
	// Get our personal validity interval...
	Interval valid = GetValidity(t);
	// and intersect it with the channels we use as input (see ChannelsUsed)
	valid &= os->obj->ChannelValidity (t, GEOM_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
	Matrix3 modmat,minv;
	
	if (mc.localData == NULL) mc.localData = new RelaxModData;
	RelaxModData *rd = (RelaxModData *) mc.localData;

	TriObject *triObj = NULL;
	PatchObject *patchObj = NULL;
	PolyObject *polyObj = NULL;
	BOOL converted = FALSE;

	// For version 4 and later, we process patch or poly meshes as they are and pass them on. 
	// Earlier versions converted to TriMeshes (done below).
	// For adding other new types of objects, add them here!
#ifndef NO_PATCHES
	if(version >= RELAXMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
		patchObj = (PatchObject *)os->obj;
		}
	else	// If it's a TriObject, process it
#endif // NO_PATCHES
	if(os->obj->IsSubClassOf(triObjectClassID)) {
		triObj = (TriObject *)os->obj;
	}
	else if (os->obj->IsSubClassOf (polyObjectClassID)) {
		polyObj = (PolyObject *) os->obj;
	}
	else	// If it can convert to a TriObject, do it
	if(os->obj->CanConvertToType(triObjectClassID)) {
		triObj = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);
		converted = TRUE;
		}
	else
		return;		// We can't deal with it!

	Mesh *mesh = triObj ? &(triObj->GetMesh()) : NULL;
#ifndef NO_PATCHES
	PatchMesh &pmesh = patchObj ? patchObj->GetPatchMesh(t) : *((PatchMesh *)NULL);
#else
	PatchMesh &pmesh = *((PatchMesh *)NULL);
#endif // NO_PATCHES

	float relax, wtdRelax; // mjm - 4.8.99
	int iter;
	BOOL boundary, saddle;

	pblock->GetValue (PB_RELAX,  t, relax,	 FOREVER);
	pblock->GetValue (PB_ITER,	 t, iter,	 FOREVER);
	pblock->GetValue (PB_BOUNDARY, t, boundary, FOREVER);
	pblock->GetValue (PB_SADDLE, t, saddle, FOREVER);

	LimitValue (relax, MIN_RELAX, MAX_RELAX);
	LimitValue (iter, MIN_ITER, MAX_ITER);

	if(triObj) {
		int i, j, max;
		DWORD selLevel = mesh->selLevel;
		// mjm - 4.8.99 - add support for soft selection
		// sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels.
		float *vsw = (selLevel!=MESH_OBJECT) ? mesh->getVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (mesh->numVerts != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			rd->SetVNum (mesh->numVerts);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=0;
				rd->nbor[i].ZeroCount();
			}
			rd->sel.ClearAll ();
			DWORD *v;
			int k1, k2, origmax;
			for (i=0; i<mesh->numFaces; i++) {
				v = mesh->faces[i].v;
				for (j=0; j<3; j++) {
					if ((selLevel==MESH_FACE) && mesh->faceSel[i]) rd->sel.Set(v[j]);
					if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+j]) rd->sel.Set(v[j]);
					if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+(j+2)%3]) rd->sel.Set(v[j]);
					origmax = max = rd->nbor[v[j]].Count();
					rd->fnum[v[j]]++;
					for (k1=0; k1<max; k1++) if (rd->nbor[v[j]][k1] == v[(j+1)%3]) break;
					if (k1==max) { rd->nbor[v[j]].Append (1, v+(j+1)%3, 1); max++; }
					for (k2=0; k2<max; k2++) if (rd->nbor[v[j]][k2] == v[(j+2)%3]) break;
					if (k2==max) { rd->nbor[v[j]].Append (1, v+(j+2)%3, 1); max++; }
					if (max>origmax) rd->vis[v[j]].SetSize (max, TRUE);
					if (mesh->faces[i].getEdgeVis (j)) rd->vis[v[j]].Set (k1);
					else if (k1>=origmax) rd->vis[v[j]].Clear (k1);
					if (mesh->faces[i].getEdgeVis ((j+2)%3)) rd->vis[v[j]].Set (k2);
					else if (k2>= origmax) rd->vis[v[j]].Clear (k2);
				}
			}
	// mjm - begin - 4.8.99
	//		if (selLevel==MESH_VERTEX) rd->sel = mesh->vertSel;
			if (selLevel==MESH_VERTEX)
				rd->sel = mesh->vertSel;
			else if (selLevel==MESH_OBJECT)
				rd->sel.SetAll ();
	// mjm - end
			rd->ivalid  = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Point3 *hold = new Point3[rd->vnum];
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = triObj->GetPoint(i);
			if (saddle) mesh->FindVertexAngles (vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
	// mjm - begin - 4.8.99
	//			if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue;
				if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue;
	// mjm - end
				if (saddle && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && (rd->fnum[i] < max)) continue;
				if (max<1) continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					if (!rd->vis[i][j]) continue;
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1) continue;
	// mjm - begin - 4.8.99
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				triObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
	//			triObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act));
	// mjm - end
			}
		}
		delete [] hold;
	}

	if (polyObj) {
		int i, j, max;
		MNMesh & mm = polyObj->mm;
		float *vsw = (mm.selLevel!=MNM_SL_OBJECT) ? mm.getVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (mm.numv != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			rd->SetVNum (mm.numv);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=0;
				rd->nbor[i].ZeroCount();
			}
			rd->sel = mm.VertexTempSel ();
			int k1, k2, origmax;
			for (i=0; i<mm.numf; i++) {
				int deg = mm.f[i].deg;
				int *vtx = mm.f[i].vtx;
				for (j=0; j<deg; j++) {
					Tab<DWORD> & nbor = rd->nbor[vtx[j]];
					origmax = max = nbor.Count();
					rd->fnum[vtx[j]]++;
					DWORD va = vtx[(j+1)%deg];
					DWORD vb = vtx[(j+deg-1)%deg];
					for (k1=0; k1<max; k1++) if (nbor[k1] == va) break;
					if (k1==max) { nbor.Append (1, &va, 1); max++; }
					for (k2=0; k2<max; k2++) if (nbor[k2] == vb) break;
					if (k2==max) { nbor.Append (1, &vb, 1); max++; }
				}
			}
			rd->ivalid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Tab<Point3> hold;
		hold.SetCount (rd->vnum);
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = mm.P(i);
			if (saddle) FindVertexAngles (mm, vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
				if ((!rd->sel[i]) && (!vsw || vsw[i] == 0) ) continue;
				if (saddle && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && (rd->fnum[i] < max)) continue;
				if (max<1) continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1) continue;
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				polyObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
			}
		}
	}

#ifndef NO_PATCHES
	else
	if(patchObj) {
		int i, j, max;
		DWORD selLevel = pmesh.selLevel;
		// mjm - 4.8.99 - add support for soft selection
		// sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels.
		float *vsw = (selLevel!=PATCH_OBJECT) ? pmesh.GetVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (pmesh.numVerts != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			int vecBase = pmesh.numVerts;
			rd->SetVNum (pmesh.numVerts + pmesh.numVecs);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=1;		// For patches, this means it's not a boundary
				rd->nbor[i].ZeroCount();
			}
			rd->sel.ClearAll ();
			for (i=0; i<pmesh.numPatches; i++) {
				Patch &p = pmesh.patches[i];
				int vecLimit = p.type * 2;
				for (j=0; j<p.type; j++) {
					PatchEdge &e = pmesh.edges[p.edge[j]];
					BOOL isBoundary = (e.patches.Count() < 2) ? TRUE : FALSE;
					int theVert = p.v[j];
					int nextVert = p.v[(j+1)%p.type];
					int nextVec = p.vec[j*2] + vecBase;
					int nextVec2 = p.vec[j*2+1] + vecBase;
					int prevEdge = (j+p.type-1)%p.type;
					int prevVec = p.vec[prevEdge*2+1] + vecBase;
					int prevVec2 = p.vec[prevEdge*2] + vecBase;
					int theInterior = p.interior[j] + vecBase;
					// Establish selection bits
					if ((selLevel==PATCH_PATCH) && pmesh.patchSel[i]) {
						rd->sel.Set(theVert);
						rd->sel.Set(nextVec);
						rd->sel.Set(prevVec);
						rd->sel.Set(theInterior);
						}
					else
					if ((selLevel==PATCH_EDGE) && pmesh.edgeSel[p.edge[j]]) {
						rd->sel.Set(e.v1);
						rd->sel.Set(e.vec12 + vecBase);
						rd->sel.Set(e.vec21 + vecBase);
						rd->sel.Set(e.v2);
						}
					else
					if ((selLevel==PATCH_VERTEX) && pmesh.vertSel[theVert]) {
						rd->sel.Set(theVert);
						rd->sel.Set(nextVec);
						rd->sel.Set(prevVec);
						rd->sel.Set(theInterior);
						}

					// Set boundary flags if necessary
					if(isBoundary) {
						rd->fnum[theVert] = 0;
						rd->fnum[nextVec] = 0;
						rd->fnum[nextVec2] = 0;
						rd->fnum[nextVert] = 0;
						}

					// First process the verts
					int work = theVert;
					max = rd->nbor[work].Count();
					// Append the neighboring vectors
					rd->MaybeAppendNeighbor(work, nextVec, max);
					rd->MaybeAppendNeighbor(work, prevVec, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);

					// Now process the edge vectors
					work = nextVec;
					max = rd->nbor[work].Count();
					// Append the neighboring points
					rd->MaybeAppendNeighbor(work, theVert, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);
					rd->MaybeAppendNeighbor(work, prevVec, max);
					rd->MaybeAppendNeighbor(work, nextVec2, max);
					rd->MaybeAppendNeighbor(work, p.interior[(j+1)%p.type] + vecBase, max);

					work = prevVec;
					max = rd->nbor[work].Count();
					// Append the neighboring points
					rd->MaybeAppendNeighbor(work, theVert, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);
					rd->MaybeAppendNeighbor(work, nextVec, max);
					rd->MaybeAppendNeighbor(work, prevVec2, max);
					rd->MaybeAppendNeighbor(work, p.interior[(j+p.type-1)%p.type] + vecBase, max);

					// Now append the interior, if not auto
					if(!p.IsAuto()) {
						work = theInterior;
						max = rd->nbor[work].Count();
						// Append the neighboring points
						rd->MaybeAppendNeighbor(work, p.v[j], max);
						rd->MaybeAppendNeighbor(work, nextVec, max);
						rd->MaybeAppendNeighbor(work, nextVec2, max);
						rd->MaybeAppendNeighbor(work, prevVec, max);
						rd->MaybeAppendNeighbor(work, prevVec2, max);
						for(int k = 1; k < p.type; ++k)
							rd->MaybeAppendNeighbor(work, p.interior[(j+k)%p.type] + vecBase, max);
						}
					}
				}
	// mjm - begin - 4.8.99
			if (selLevel==PATCH_VERTEX) {
				for (int i=0; i<pmesh.numVerts; ++i) {
					if (pmesh.vertSel[i]) rd->sel.Set(i);
				}
			}
			else if (selLevel==PATCH_OBJECT) rd->sel.SetAll();
	// mjm - end
			rd->ivalid  = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Point3 *hold = new Point3[rd->vnum];
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = patchObj->GetPoint(i);
			if (saddle)
				FindVertexAngles(pmesh, vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
	// mjm - begin - 4.8.99
	//			if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue;
				if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue;
	// mjm - end
				if (saddle && (i < pmesh.numVerts) && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && !rd->fnum[i]) continue;
				if (max<1)
					continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1)
					continue;
	// mjm - begin - 4.8.99
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				patchObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
	//			patchObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act));
	// mjm - end
			}
		}
		delete [] hold;
		patchObj->patch.computeInteriors();
		patchObj->patch.ApplyConstraints();
	}
#endif // NO_PATCHES
	
	if(!converted) {
		os->obj->SetChannelValidity(GEOM_CHAN_NUM, valid);
	} else {
		// Stuff converted object into the pipeline!
		triObj->SetChannelValidity(TOPO_CHAN_NUM, valid);
		triObj->SetChannelValidity(GEOM_CHAN_NUM, valid);
		triObj->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		triObj->SetChannelValidity(MTL_CHAN_NUM, valid);
		triObj->SetChannelValidity(SELECT_CHAN_NUM, valid);
		triObj->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		triObj->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = triObj;
	}
}
Exemple #6
0
void ExtrudeMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
	{	
//DebugPrint(_T("Extrude modifying object\n"));

	// Get our personal validity interval...
	Interval valid = GetValidity(t);
	// and intersect it with the channels we use as input (see ChannelsUsed)
	valid &= os->obj->ChannelValidity(t,TOPO_CHAN_NUM);
	valid &= os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	
	int output;
	pblock->GetValue(PB_OUTPUT, TimeValue(0), output, FOREVER);

	switch (output) {
	case NURBS_OUTPUT:
#ifndef NO_NURBS
		{
		// Here is where all the fun stuff happens -- GenerateExtrudeSurface fills in the EM,
		// then we stuff the EditableSurface into the pipeline.
		ShapeObject *shape = (ShapeObject *)os->obj;
			float amount;

		BOOL texturing, genMatIds, useShapeIDs;
		pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER);
		pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIds, FOREVER);
		pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER);

		int levels,capStart,capEnd,capType;

		pblock->GetValue(PB_SEGS,t,levels,FOREVER);
		if (levels<1) levels = 1;
		pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER);
		pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER);
		pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER);

		pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
		LimitValue(amount, -1000000.0f, 1000000.0f);


		BOOL suspended = FALSE;
		if (theHold.Holding()) {
			theHold.Suspend();
			suspended = TRUE;
		}
		Object *nobj = CreateNURBSExtrudeShape(ip, GetString(IDS_RB_EXTRUDE), t, shape, amount,
								capStart, capEnd, capType, texturing, genMatIds, useShapeIDs);
		if (suspended) {
			theHold.Resume();
		}

        // We only set geom validity because we preserve animation on clone
        // and copying other cahnnels causes problems -- SCM 9/2/97
		nobj->SetChannelValidity(GEOM_CHAN_NUM, valid);

		os->obj = nobj;
		break;}
#endif
#ifndef NO_PATCHES
	case PATCH_OUTPUT: {
		// Here is where all the fun stuff happens -- BuildPatchFromShape fills in the PatchObject's patch mesh,
		// then we stuff the PatchObject into the pipeline.
		PatchObject *pat = new PatchObject;
		BuildPatchFromShape(t, mc, os, pat->patch);

		pat->SetChannelValidity(TOPO_CHAN_NUM, valid);
		pat->SetChannelValidity(GEOM_CHAN_NUM, valid);
		pat->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		pat->SetChannelValidity(MTL_CHAN_NUM, valid);
		pat->SetChannelValidity(SELECT_CHAN_NUM, valid);
		pat->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		pat->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = pat;
		break;}
#endif // NO_PATCHES
	case MESH_OUTPUT: {
		// Here is where all the fun stuff happens -- BuildMeshFromShape fills in the TriObject's mesh,
		// then we stuff the TriObj into the pipeline.
		TriObject *tri = CreateNewTriObject();
		BuildMeshFromShape(t, mc, os, tri->GetMesh());

		tri->SetChannelValidity(TOPO_CHAN_NUM, valid);
		tri->SetChannelValidity(GEOM_CHAN_NUM, valid);
		tri->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		tri->SetChannelValidity(MTL_CHAN_NUM, valid);
		tri->SetChannelValidity(SELECT_CHAN_NUM, valid);
		tri->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		tri->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = tri;
		break; }
#ifdef XXDESIGN_VER
	case AMSOLID_OUTPUT: {
		//Create an extrusion solid using Facet Modeler
		Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID);
		assert(solid);
		if(solid)
		{
			IGeomImp* cacheptr = (IGeomImp*)(solid->GetInterface(I_GEOMIMP));
			assert(cacheptr);
			if(cacheptr)
			{
				bool res = BuildAMSolidFromShape(t, mc, os, cacheptr);
				solid->ReleaseInterface(I_GEOMIMP, cacheptr);
				if(!res)
				{
					valid.SetInstant(t);
//					assert(!cacheptr->isNull());
				}
				for(int i=0; i<NUM_OBJ_CHANS;i++)
					solid->SetChannelValidity(i, valid);
				os->obj = solid;
			}

		}

		break; }
#endif
	}

	os->obj->UnlockObject();
	}